gpt4 book ai didi

python - 继承子类 MRO 的别名

转载 作者:行者123 更新时间:2023-11-28 20:59:30 25 4
gpt4 key购买 nike

class parent:
def fun1(self):
print("foo")

fun2 = fun1

class child(parent):
def fun1(self):
print("bar")

child().fun2()

此代码输出“foo”。我很确定我明白为什么会这样,但我想知道是否有一种直接的方法来实现我想要的东西(根据 MRO 运行的可继承别名,因此它输出“bar”)或者这是为什么糟糕的编程习惯。

最佳答案

无法直接做您想做的事。

要了解原因,您需要了解方法查找的工作方式。在 the Descriptor HOWTO 中有详细解释。 ,我试着写了一个不太专家级的解释here ,所以我假设您阅读了这两篇文章并展示了效果:

>>> child.fun1
<function __main__.child.fun1>
>>> child.fun2
<function __main__.parent.fun1>
>>> child().fun2
<bound method parent.fun1 of <__main__.child object at 0x10b735ba8>>

请注意 child.fun2parent.fun1,而不是 child.fun1。这解释了为什么 child().fun2 最终成为围绕 parent.fun1 的绑定(bind)方法,即使 self 最终成为 child 实例。为什么?好吧,显然 fun2 不在 child.__dict__ 中(或者我们不需要 MRO)。在 parent.__dict__ 中,它只能是 parent.fun1

那么,解决方法是什么?

您可以将 fun2 变成一个转发给 fun2property,正如 Patrick Haugh 所建议的那样。或者你可以这样做:

def fun2(self):
return self.fun1()

这个解决方案的好处是非常简单——任何会 Python 的人都会明白它为什么有效。

但 Patrick 的解决方案的优势在于不仅可以生成 child().fun2(),还可以生成 child().fun2(作为一个对象,您可以传递、比较身份等)按您希望的方式工作。


与此同时,有一个习惯用法与您的要求密切相关,其中一组您不希望覆盖的公共(public)方法调用您执行的“ protected ”实现方法。例如,一个简单的一维数组数学类可能会这样做:

def _math(lhs, rhs, op):
# not actually a useful implementation...
return [op(x, y) for x, y in zip(lhs, rhs)]
def __add__(self, other):
return self._math(other, add)
def __radd__(self, other):
return self._math(other, add)
# etc.

现在 __add____radd__ 之间没有不对称,只有“公共(public)”接口(interface)(__add____radd__) 和“ protected ”的 (_math)。

关于python - 继承子类 MRO 的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49459370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com