Инкапсуляция и @property
Тема дорожной карты · Python Programming
Python не форсит приватные атрибуты; есть соглашение: _name — «внутренний», __name — name-mangling. Смысл инкапсуляции в сохранении инвариантов при том, что вызывающие пользуются обычным синтаксисом атрибута (obj.email = "x"). @property позволяет начать с публичных атрибутов и позже добавить валидацию, вычисляемые значения или deprecation-предупреждения, не ломая API. @x.setter/@x.deleter — только когда реально нужно; атрибут, который просто хранит значение, должен оставаться обычным атрибутом. Берегись: properties прячут I/O за невинным обращением, а property поверх dataclass-записей часто запах — лучше валидировать в конструкторе.
Как это работает
Инкапсуляция и @property в Python использует class для связи состояния (атрибуты) и поведения (методы). __init__ инициализирует экземпляры; первый параметр self — сам экземпляр. Методы бывают instance (self), class (@classmethod, cls) или static (@staticmethod). Наследование: class Sub(Base): — допускается множественное; Method Resolution Order (MRO) считается C3-линеаризацией. Dunder-методы (__add__, __len__, __iter__) встраиваются в синтаксис Python (перегрузка операторов, len(), for). @property даёт attribute-like доступ с логикой геттера.
Когда применять
Класс — когда (а) состояние и поведение принадлежат вместе, (б) есть несколько связанных операций над теми же данными, (в) функция с кучей параметров была бы яснее как self-contained объект. Не создавайте класс, если хватит функции или dataclass — Python это не Java; модули с набором функций часто бьют поверхностные иерархии классов. Композиция важнее наследования, кроме случаев настоящего "is-a".
Типичные ошибки
Ловушки Инкапсуляция и @property: mutable атрибуты на уровне класса, общие между экземплярами (class C: items = [] — каждый C() делит этот список); глубокие иерархии наследования, скрывающие, где живёт поведение (используйте композицию или миксины, максимум 1-2 уровня); перегрузка __eq__ без __hash__ (объект становится unhashable, ломает ключи словаря); злоупотребление @staticmethod для того, что должно быть функцией модуля. __init__ короткий — тяжёлая работа в factory или classmethod.
Связанные понятия
Полезные ресурсы
Проверить знания (1)
Загрузка вопросов…