class parent:
def fun1(self):
print("foo")
fun2 = fun1
class child(parent):
def fun1(self):
print("bar")
child().fun2()
此代码输出" foo"。我很确定我理解为什么会这样,但我想知道是否有一种直接的方式来实现我想要的东西(根据MRO行为的可继承别名,所以它输出" bar&# 34;)或者这是一个错误的编程实践的原因。
答案 0 :(得分:3)
没有办法直接做你想做的事。
要了解原因,您需要了解方法查找的工作方式。我在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.fun2
是parent.fun1
,而不是child.fun1
。这解释了为什么child().fun2
最终成为parent.fun1
的绑定方法,即使self
最终为child
个实例。为什么?好吧,显然fun2
不在child.__dict__
中(或者我们不需要MRO)。在parent.__dict__
中,它不能是parent.fun1
。
那么,有哪些解决方法?
正如Patrick Haugh建议的那样,您可以将fun2
变为property
转发到fun2
。或者你可以这样做:
def fun2(self):
return self.fun1()
这个解决方案有一个简单的好处 - 任何能够使用Python的人都能理解它的工作原理。
但帕特里克的解决方案的优点是不仅可以child().fun2()
,还可以child().fun2
(作为一个可以传递的对象,比较身份等等)的工作方式就像你一样想要它。
与此同时,有一个与你所要求的内容密切相关的习惯用语,你不希望覆盖的一套公共方法称为“受保护的”#34;&#34;你做的实现方法。例如,一个简单的1D数组数学类可能会这样做:
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__
之间没有不对称,只有公共&#34;界面(__add__
和__radd__
)和&#34;受保护的&#34;一个(_math
)。
答案 1 :(得分:2)
这是一种非常直接的方式 - 完全可以:
class Parent:
def fun1(self):
print("foo")
def fun2(self):
return self.fun1()
class Child(Parent):
def fun1(self):
print("bar")
Child().fun2() # -> bar
答案 2 :(得分:1)
您可以将fun2
作为返回self.fun1
class Parent:
def fun1(self):
print('foo')
@property
def fun2(self):
return self.fun1
class Child(Parent):
def fun1(self):
print('bar')
Child().fun2()
# bar