Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗pyOpAaSa 109 of 174 menu
◀ ▶

Запись свойств через __setattr__ в ООП в Python

Метод __setattr__ вызывается при каждой попытке записать атрибут через точку - и в новое имя, и в уже существующее, и в приватное. В качестве параметров он принимает имя свойства и значение, которое ему пытаются присвоить.

Давайте посмотрим на практическом примере. Пусть у нас дан вот такой класс Test:

class Test: pass

Давайте сделаем в этом классе метод __setattr__, который будет выводить имя свойства, к которому произошло обращение, и значение, которое этому свойству пытаются установить:

class Test: def __setattr__(self, name, value): print(name, value)

Проверим работу нашего класса:

test = Test() test.prop = 'value' # __setattr__ выведет 'prop value'

Давайте теперь будем устанавливать значение свойству, имя которого пришло в параметре name:

class Test: def __setattr__(self, name, value): super().__setattr__(name, value) # устанавливаем значение

Теперь мы сможем записывать данные снаружи, в том числе в новые имена:

test = Test() test.prop1 = 1 # запишем 1 test.prop2 = 2 # запишем 2

Давайте попробуем записать данные в несуществующее свойство - это будет работать:

test = Test() test.prop3 = 3 # запишем 3 print(test.prop3) # выведет 3

Пусть мы не хотим разрешать записывать в несуществующие свойства. И, вообще, хотим разрешить запись только в свойства prop1 и prop2.

Это легко сделать - достаточно в методе __setattr__ добавить соответствующее условие:

class Test: def __setattr__(self, name, value): # Напишем условие: if name == 'prop1' or name == 'prop2': super().__setattr__(name, value) def __getattr__(self, name): return super().__getattribute__(name)

Если таких свойств будет много, то не очень удобно перечислять их все в условии.

Давайте запишем разрешенные для записи свойства в список и будем проверять наличие свойства в этом списке с помощью оператора in:

class Test: def __setattr__(self, name, value): properties = ['prop1', 'prop2'] # разрешенные свойства if name in properties: super().__setattr__(name, value) def __getattr__(self, name): return super().__getattribute__(name)

На самом деле, конечно же, не стоит разрешать всем подряд записывать в приватные свойства, иначе пропадает суть этих приватных свойств (проще сделать их публичными и все).

Поэтому метод __setattr__ следует применять только тогда, когда в этом действительно есть необходимость.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить