【问题标题】:How to override a function when Parent already explicitly `setattr` the same function?当 Parent 已经明确地“setattr”相同的函数时,如何覆盖一个函数?
【发布时间】:2020-06-17 07:48:28
【问题描述】:

我创建的“最小”示例:

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 显式定义为C 类的wave 方法,虽然不是通过更常见的函数定义,而是使用setattr 代替。然后我们有继承A 的类BB 尝试用自己的方法覆盖wave 方法,但是,这是不可能的,这是怎么回事?我该如何解决?

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

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

【问题讨论】:

    标签: python inheritance setattr


    【解决方案1】:

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

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

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

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

    删除实例属性后,wave() 函数随后从类字典中获取:

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

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

    当时我还写了一个blog post,更详细地解释了属性查找的工作原理。

    【讨论】:

    • 谢谢,这正是我要找的!
    • 我还用我的博客文章的链接更新了我的答案,以防您想了解有关属性查找机制的更多详细信息(将所有详细信息包含在答案本身)。
    猜你喜欢
    • 2014-09-08
    • 2011-06-15
    • 2017-06-25
    • 2016-04-19
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多