拥有以下代码:
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)
以下条件/假设:
Parent
在其__setattr__
实现中执行了一些操作,使Child
在设置新的类属性时引发异常。Parent
源代码无法修改(可能是猴子修补,但它是外部依赖项)。有没有办法解决这个问题?在设置Parent
之前,我可以“废弃”__setattr__
的{{1}}实施吗?我可以在y
中重新实现此方法,以使其按预期工作吗?
答案 0 :(得分:2)
您可以通过在MRO中查找 next __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)
,但前提是Parent
直接来自object
,而不是来自同时实施__setattr__
的其他类。使用super()
会在继承树中找到 next __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
答案 1 :(得分:1)
您可以调用基础__setattr__
:
object.__setattr__(self, 'y', 2)
请注意,这完全绕过Parent
的{{1}},因此这样做可能会破坏__setattr__
中的各种不变量。
答案 2 :(得分:0)
在__setattr__
中添加Child
方法,您可以忽略Parent
中的方法:
class Child(Parent):
...
def __setattr__(self, name, value):
# do whatever you want;