2010-06-29 158 views
12

我只花了太长像下面这样的错误:Python:类可以禁止客户端设置新的属性吗?

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


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

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

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

其次,在定义Odp时,有没有一种方法可以禁止这种情况,从而为自己省去了麻烦?

+1

可能的重复:http://stackoverflow.com/questions/3079306/how-to-protect-againt-typos-when-setting-value-for-class-members – detly 2010-06-29 03:06:30

回答

16

您可以实现__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成功为你做希望能够通过在类级别设置的属性或通过在__init__方法使用object.__setattr__而设置,例如名称比直接属性分配。 (要禁止设置属性而不是其实例您必须使用类似的特殊方法定义自定义元类)。

+0

你为什么选择TypeError?也许是错误的,我脑海中有'AttributeError'。 – n611x007 2015-01-21 10:04:22

+2

“不支持XX分配”消息(例如对于项目)使用“TypeError”,更容易混淆措辞“没有属性XX”的人使用'AttributeError',所以我猜或者确定(尽管不完美)。 – 2015-01-21 15:01:56

相关问题