Python: Может ли класс запретить клиентам устанавливать новые атрибуты?
Я просто потратил слишком много времени на ошибку, как показано ниже:
>>> class Odp():
def __init__(self):
self.foo = "bar"
>>> o = Odp()
>>> o.raw_foo = 3 # oops - meant o.foo
У меня есть класс с атрибутом. Я пытался установить это, и удивлялся, почему это не имело никакого эффекта. Затем я вернулся к исходному определению класса и увидел, что атрибут был назван как-то немного по-другому. Таким образом, я создавал / устанавливал новый атрибут вместо того, который предназначался для.
Во-первых, разве это не тот тип ошибок, который должны предотвращать статически типизированные языки? В этом случае, в чем преимущество динамической типизации?
Во-вторых, есть ли способ, которым я мог бы запретить это при определении Odp
и таким образом спас себя от неприятностей?
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
успешно для имен, которые вы хотите установить, например, установив атрибуты на уровне класса или используя object.__setattr__
в вашем __init__
метод, а не прямое присвоение атрибута. (Чтобы запретить установку атрибутов в классе, а не в его экземплярах, вам придется определить собственный метакласс с помощью аналогичного специального метода).