← Все вопросы

Как сделать атрибут «только для чтения» через property без сеттера?

Задан 13 дней назад402 просмотров3 ответа
13

Хочу, чтобы у объекта было поле, которое можно прочитать (obj.value), но нельзя присвоить (obj.value = 5 должно падать). Как это сделать аккуратно, без подчёркиваний и соглашений «не трогай»?

3 ответа

22
✓ Принятый ответ — помог автору

Сделай @property и просто не определяй сеттер. Тогда чтение работает, а присваивание кидает AttributeError:

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @property
    def area(self):
        return 3.14 * self._radius ** 2

c = Circle(5)
print(c.radius)   # 5
print(c.area)     # 78.5 — вычисляется на лету
c.radius = 10     # AttributeError: can't set attribute

Реальное значение прячут в _radius, а наружу торчит только геттер radius. Бонус: через property удобно делать вычисляемые поля (area), которые считаются из других при каждом обращении и которые логично нельзя присваивать напрямую. Это и есть нормальный питоновский read-only без «джентльменских соглашений».

Рустам Закиров Вычисляемые свойства типа area — мой любимый кейс property · 4 дня назад
9

@property без @x.setter. Присваивание тогда падает с AttributeError.

3

property без сеттера.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект