如何在Python中的新样式类上正确覆盖__setattr__和__getattribute__?

时间:2011-08-12 15:10:14

标签: python python-3.x inheritance python-2.x setattr

我想覆盖我的Python类的__getattribute____setattr__方法。我的用例是通常的:我有一些我想要处理的特殊名称,我想要其他任何东西的默认行为。对于__getattribute__,我似乎可以通过提升AttributeError来请求默认行为。但是,如何在__setattr__中实现相同的目标?这是一个简单的例子,实现了一个具有不可变字段“A”,“B”和“C”的类。

class ABCImmutable(SomeSuperclass):
    def __getattribute__(self, name):
        if name in ("A", "B", "C"):
            return "Immutable value of %s" % name
        else:
            # This should trigger the default behavior for any other
            # attribute name.
            raise AttributeError()

    def __setattr__(self, name, value):
        if name in ("A", "B", "C"):
            raise AttributeError("%s is an immutable attribute.")
        else:
            # How do I request the default behavior?
            ???

代替问号的是什么?对于旧式类,答案显然是self.__dict__[name] = value,但文档表明这对于新式类来说是错误的。

2 个答案:

答案 0 :(得分:40)

这是

super(ABCImmutable, self).__setattr__(name, value)

在Python 2中,或

super().__setattr__(name, value)
在Python 3中

此外,提升AttributeError 您如何回归__getattribute__的默认行为。您可以使用

回退到默认值
return super(ABCImmutable, self).__getattribute__(name)

在Python 2或

return super().__getattribute__(name)

在Python 3上。

提升AttributeError会跳过默认处理并转到__getattr__,或者如果没有AttributeError,则只在调用代码中生成__getattr__

请参阅Customizing Attribute Access上的文档。

答案 1 :(得分:6)

SomeSuperclass.__setattr__(self, name, value)