В Python декоратор @property позволяет создавать "виртуальные" атрибуты — методы, которые выглядят и используются как обычные поля, но отрабатывают логику геттера, сеттера или делитера. Это удобно для создания вычисляемых свойств или контроля доступа к данным.
Пример:
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 (вызывается как свойство, не функция) r.width = 10 # setter вызван автоматически
Можно ли использовать только один @property (get-метод), не определяя сеттер? Что произойдет, если попытаться изменить такой атрибут?
Ответ: Можно определить только геттер @property без сеттера (и делитера). Такой атрибут будет read-only, попытка присвоения вызовет AttributeError.
class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: can't set attribute
История
Пытались сериализовать объект с помощью стандартной библиотеки, используя vars(obj), чтобы получить словарь атрибутов. Оказалось, что property-методы не входят в вывод __dict__, их значения не сериализовались, что привело к утечке данных.
История
В проекте забыли добавить сеттер для property, в итоге попытка изменить значение вычисляемого поля приводила к ошибке времени выполнения, хотя по логике архитектуры это ожидалось.
История
В работающем коде вычисление значения property допускало тяжелые или небезопасные операции, которые неожиданно вызывались при каждом обращении к свойству. Это снизило производительность и привело к блокирующим вызовам в многопоточном коде.