ProgrammingPython Developer

What are annotated (property) attributes in Python, how does the built-in decorator @property work, and why (and when) is it used? Provide examples and discuss common mistakes when working with property.

Pass interviews with Hintsage AI assistant

Answer.

In Python, the @property decorator allows you to create "virtual" attributes — methods that look and behave like regular fields but implement the logic of a getter, setter, or deleter. This is useful for creating computed properties or controlling access to data.

Example:

class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): if value <= 0: raise ValueError('Width must be positive') self._width = value r = Rectangle(3, 4) print(r.area) # 12 (called as a property, not a function) r.width = 10 # setter is called automatically

Trick question.

Can you use only one @property (getter method) without defining a setter? What happens if you try to change such an attribute?

Answer: You can define only a getter @property without a setter (and deleter). Such an attribute will be read-only, and attempting to assign to it will raise AttributeError.

class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: can't set attribute

Examples of real mistakes due to ignorance of the nuances of the topic.


Story

Tried to serialize an object using the standard library with vars(obj) to get a dictionary of attributes. It turned out that property methods are not included in the output of __dict__, and their values weren't serialized, leading to data leakage.


Story

In the project, we forgot to add a setter for the property, which led to a runtime error when trying to change the value of a computed field, although this was expected according to the architecture logic.


Story

In working code, the computation of the property value allowed heavy or unsafe operations, which were unexpectedly invoked each time the property was accessed. This reduced performance and led to blocking calls in multithreaded code.