简体   繁体   English

当 Parent 已经明确地“setattr”相同的 function 时,如何覆盖 function?

[英]How to override a function when Parent already explicitly `setattr` the same function?

A 'minimal' example I created:我创建的“最小”示例:

class C:
    def wave(self):
        print("C waves")

class A:
    def __init__(self):
        c = C()
        setattr(self, 'wave', getattr(c, 'wave'))

class B(A):
    def wave(self):
        print("B waves")

>>> a = A()
>>> a.wave()
C waves # as expected
>>> b = B()
>>> b.wave()
C waves # why not 'B waves'?
>>> 

In the example, class A explicitly defined its method wave to be class C 's wave method, although not through the more common function definition, but using setattr instead. In the example, class A explicitly defined its method wave to be class C 's wave method, although not through the more common function definition, but using setattr instead. Then we have class B that inherits A , B tries to override wave method with its own method, however, that's not possible, what is going on?然后我们有继承A class BB尝试用自己的方法覆盖wave方法,但是,这是不可能的,这是怎么回事? how can I work around it?我该如何解决?

I want to keep class A 's setattr style definition if at all possible, please advise.如果可能的话,我想保留 class Asetattr样式定义,请告知。

I've never systematically learned Python so I guess I am missing some understanding regarding how Python's inheritance and setattr work.我从来没有系统地学习过 Python 所以我想我对 Python 的 inheritance 和setattr的工作方式有一些了解。

Class A sets the wave() method as its instance attribute in __init__() . Class A 在__init__()中将wave()方法设置为其实例属性。 This can be seen by inspecting the instance's dict:这可以通过检查实例的字典来看到:

>>> b.__dict__
{'wave': <bound method C.wave of <__main__.C object at 0x7ff0b32c63c8>>}

You can get around this by deleting the instance member from b您可以通过从b中删除实例成员来解决此问题

>>> del b.__dict__['wave']
>>> b.wave()
B waves

With the instance attribute removed, the wave() function is then taken from the class dict:删除实例属性后, wave() function 然后从 class 字典中获取:

>>> B.__dict__
mappingproxy({'__module__': '__main__',
              'wave': <function __main__.B.wave(self)>,
              '__doc__': None})

The thing to note here is that when Python looks up an attribute, instance attributes take precedence over the class attributes (unless a class attribute is a data descriptor , but this is not the case here).这里要注意的是,当 Python 查找属性时,实例属性优先于 class 属性(除非 class 属性是数据描述符,但这里不是)。

I have also written a blog post back then explaining how the attribute lookup works in even more detail.那时我还写了一篇博文,更详细地解释了属性查找的工作原理。

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

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