当父函数已经显式地“setattr”相同的函数时,如何重写该函数?

2024-04-28 05:27:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个“最小”示例:

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'?
>>> 

在该示例中,类A显式地将其方法wave定义为类Cwave方法,尽管不是通过更常见的函数定义,而是使用setattr。然后我们有类B继承AB尝试用自己的方法重写wave方法,但是,这是不可能的,发生了什么?我怎样才能解决这个问题

我想保留类Asetattr样式定义,如果可能的话,请告知

我从来没有系统地学习过Python,所以我想我对Python的继承和setattr如何工作缺乏一些理解


Tags: 方法self示例定义initdefaswave
1条回答
网友
1楼 · 发布于 2024-04-28 05:27:24

类A将wave()方法设置为__init__()中的实例属性。这可以通过检查实例的dict看到:

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

您可以通过从b中删除实例成员来解决这个问题

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

移除instance属性后,将从类dict中获取wave()函数:

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

这里需要注意的是,当Python查找属性时,实例属性优先于类属性(除非类属性是数据descriptor,但这里不是这种情况)

我还写了一篇blog post文章,更详细地解释了属性查找的工作原理

相关问题 更多 >