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

Rya*_*son 38 python inheritance python-2.x setattr python-3.x

我想覆盖我的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?
            ???
Run Code Online (Sandbox Code Playgroud)

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

Han*_*Gay 42

它的

super(ABCImmutable, self).__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)

在Python 2中,或

super().__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)

在Python 3中.

另外,饲养AttributeError不是你如何退回到默认行为__getattribute__.你回到默认值

return super(ABCImmutable, self).__getattribute__(name)
Run Code Online (Sandbox Code Playgroud)

在Python 2或

return super().__getattribute__(name)
Run Code Online (Sandbox Code Playgroud)

在Python 3上.

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

请参阅有关自定义属性访问的文档.

  • 关闭,但你不需要第二个"自我".你会这样称呼它:super(ABCImmutable,self).__ setattr __(name,value)否则你将得到"预期的2个参数,但得到3个"异常. (5认同)

Jea*_*not 6

SomeSuperclass.__setattr__(self, name, value)

  • 你也可以在3.x中使用super:`super(ABCImmutable,self).__ setattr __(name,value)`in python 2.x或`super().__ setattr __(name,value)`.也许你想看看这个:http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ (3认同)