Properties in Python emerged as a way to elegantly implement encapsulation of attributes, similar to getters and setters in other languages (Java/C++), but without the need to explicitly call methods. Before properties, accessing variables had to be implemented through explicit get/set methods, complicating and cluttering the class interface.
The problem is to provide the class user with a transparent interface to work with attributes (using dot notation obj.x) while being able to control the logic of computation, validation, caching, or validation of values under the hood. Without properties, changing the internal implementation requires changing all calls, which leads to widespread errors and reduced extensibility.
The solution is the @property decorator, which allows a method to be turned into an attribute while hiding the computation, validation, or lazy loading logic inside methods, without changing the external class interface. A getter is implemented as read-only, writing is organized through .setter, and deletion via .deleter.
Example code:
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): # 'area' can now be read like an attribute return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): # automatically called on assignment rect.width = ... assert value > 0, "Width must be positive" self._width = value rect = Rectangle(3, 4) print(rect.area) # 12 rect.width = 10 print(rect.area) # 40
Key features:
Can property work with class methods or static methods?
No. property only creates instance-level properties. For class-level use special descriptors or @classmethod-property (implemented manually).
If a property is declared with only a getter and no setter, can we assign a value to the attribute?
No. Such a property is read-only; an attempt to assign will raise an AttributeError.
What happens if an exception occurs inside the setter (e.g., assert)?
The exception will propagate out, the assignment will not occur, and the attribute's value will remain unchanged. This is often used for validation.
Negative case: Public class attributes, changing them without control.
Pros: fast, straightforward.
Cons: cannot change internal logic without rewriting client code, potential inconsistent states.
Positive case: Encapsulation through property, logic in getter/setter, strict checks.
Pros: flexibility, control, transparency, safe evolution of API.
Cons: slightly more code, minor complication during debugging.