Python: класс может запретить клиентам, устанавливающим новые атрибуты?

Я просто тратил слишком долго на ошибку как следующее:

>>> class Odp():
    def __init__(self):
        self.foo = "bar"


>>> o = Odp()
>>> o.raw_foo = 3 # oops - meant o.foo

У меня есть класс с атрибутом. Я пытался установить его и задавался вопросом, почему это не имело никакого эффекта. Затем я вернулся к исходному определению класса и видел, что атрибут назвали чем-то немного отличающимся. Таким образом я создавал/устанавливал новый атрибут вместо того, предназначенного для.

Прежде всего это не точно тип ошибки, которую статически типизированные языки, как предполагается, предотвращают? В этом случае, каково преимущество динамического контроля типов?

Во-вторых, есть ли способ, которым я, возможно, запретил это при определении Odp, и таким образом сохраненный я проблема?

12
задан Nick Heiner 29 June 2010 в 02:58
поделиться

1 ответ

Вы можете реализовать для этой цели метод __ setattr __ - он намного надежнее, чем __ slots __ , который часто используется для этих целей неправильно (например, , __ slots __ автоматически «теряется» при наследовании класса, тогда как __ setattr __ сохраняется, если явно не переопределено).

def __setattr__(self, name, value):
  if hasattr(self, name):
    object.__setattr__(self, name, value)
  else:
    raise TypeError('Cannot set name %r on object of type %s' % (
                    name, self.__class__.__name__))

Вам необходимо убедиться, что hasattr успешно применяется для имен, которые вы делаете хотите установить, например, установив атрибуты на уровне класса или используя объект .__ setattr __ в вашем методе __ init __ , а не прямое присвоение атрибута. (Чтобы запретить установку атрибутов в классе , а не в его экземплярах , вам придется определить собственный метакласс с помощью аналогичного специального метода).

21
ответ дан 2 December 2019 в 07:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: