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

Свойства только для чтения в ООП в Python

Давайте рассмотрим класс, в котором все свойства приватные:

class Test: def __init__(self): object.__setattr__(self, '__prop1', 1) object.__setattr__(self, '__prop2', 2)

Теперь сделаем так, чтобы эти свойства во внешнем мире были доступны только для чтения. Ранее мы такое уже делали через декоратор property: геттер без сеттера.

Другой способ - запретить запись в методе __setattr__, а чтение оставить через обычные имена prop1 и prop2. Значения лежат в приватных полях, снаружи их подменяет __getattr__:

class Test: def __init__(self): object.__setattr__(self, '__prop1', 1) object.__setattr__(self, '__prop2', 2) def __getattr__(self, name): if name in ('prop1', 'prop2'): key = f'_{type(self).__name__}__{name}' return object.__getattribute__(self, key) raise AttributeError(name) def __setattr__(self, name, value): raise AttributeError("can't set attribute " + name)

Воспользуемся им для чтения свойств:

test = Test() print(test.prop1) # выведет 1 print(test.prop2) # выведет 2

Попытка записать что-то в свойство приведет к ошибке:

test = Test() test.prop1 = 2 # выдаст ошибку

Это именно то, что нам нужно: свойство можно прочитывать, но нельзя записывать.

Попытка прочитать несуществующее свойство выдаст ошибку:

test = Test() print(test.prop3) # выдаст ошибку

Обратите также внимание на следующий нюанс: когда мы делали свойства только для чтения через property, то для чтения использовали метод-геттер под декоратором.

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

Пусть дан вот такой класс User, свойства которого доступны только для чтения с помощью геттеров:

class User: def __init__(self, name, age): self.__name = name self.__age = age def get_name(self): return self.__name def get_age(self): return self.__age

Переделайте код этого класса так, чтобы вместо геттеров чтение шло через имена name и age, а запись снаружи запрещал метод __setattr__.

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