繁体   English   中英

Python:忽略父级__setattr__

[英]Python: Ignoring parent __setattr__

具有以下代码:

class Parent():
    def __init__(self):
        pass

    def __setattr__(self, name, value):
        raise RuntimeError()


class Child(Parent):
    def __init__(self):
        super().__init__()
        self.y = 2


if __name__ == '__main__':
    print(Child().y)

以及以下条件/假设:

  • Class Parent在其__setattr__实现中执行了__setattr__ ,使Child在设置新的类属性时引发异常。
  • Parent类的源代码无法修改(可以进行猴子修补,但它是外部依赖项)。

有办法解决吗? 在设置y之前,我可以“ __setattr__Parent__setattr__实现吗? 我可以在Child重新实现此方法以使其按预期工作吗?

您可以通过在MRO中查找下一个 __setattr__方法来绕过该方法。 告诉super()过去的 Parent

class Child(Parent):
    def __init__(self):
        super().__init__()
        self.y = 2

    def __setattr__(self, name, value):
        # skip Parent.__setattr__
        super(Parent, self).__setattr__(name, value)

请注意,通常应该使用与super()的当前类不同的类; 这是一个适当的例外,但是请在生产代码中添加注释,以说明执行此操作的原因。

也可以使用object.__setattr__(self, name, value) ,但__setattr__Parent直接从object继承,而不要从也实现__setattr__其他类__setattr__ 使用super()将在继承树中找到下一个 __setattr__实现。

演示:

>>> class Parent():
...     def __init__(self):
...         pass
...     def __setattr__(self, name, value):
...         raise RuntimeError()
...
>>> class Child(Parent):
...     def __init__(self):
...         super().__init__()
...         self.y = 2
...     def __setattr__(self, name, value):
...         # skip Parent.__setattr__
...         super(Parent, self).__setattr__(name, value)
...
>>> Child().y
2

您可以调用基本的__setattr__

object.__setattr__(self, 'y', 2)

请注意,这完全绕过了Parent__setattr__ ,因此这样做可能会破坏Parent各种不变量。

Child添加__setattr__方法,您可以忽略Parent

class Child(Parent):
    ...
    def __setattr__(self, name, value):
        # do whatever you want;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM