Python:类可以禁止客户端设置新属性吗?

时间:2010-06-29 02:58:31

标签: python oop typing

我只是花了太长时间来处理以下错误:

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


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

我有一个属性的类。我试图设置它,并想知道它为什么没有效果。然后,我回到原始的类定义,并看到该属性被命名为稍微不同的东西。因此,我正在创建/设置一个新属性而不是那个属性。

首先,这不是静态类型语言应该阻止的错误类型吗?在这种情况下,动态类型的优势是什么?

其次,在定义Odp时,有没有办法禁止这样做,从而为自己省去了麻烦?

1 个答案:

答案 0 :(得分:21)

您可以为此目的实施__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__方法中的{1}}而不是直接属性分配。 (要禁止在而不是实例上设置属性,您必须使用类似的特殊方法定义自定义元类。)