简体   繁体   中英

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. 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? how can I work around it?

I want to keep class A 's setattr style definition if at all possible, please advise.

I've never systematically learned Python so I guess I am missing some understanding regarding how Python's inheritance and setattr work.

Class A sets the wave() method as its instance attribute in __init__() . 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

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

With the instance attribute removed, the wave() function is then taken from the class dict:

>>> 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).

I have also written a blog post back then explaining how the attribute lookup works in even more detail.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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