class parent:
def fun1(self):
print("foo")
fun2 = fun1
class child(parent):
def fun1(self):
print("bar")
child().fun2()此代码输出"foo“。我非常肯定我理解为什么会发生这种情况,但我想知道是否有一种直接的方法来实现我想要的东西(根据MRO行为的可继承别名,因此它输出"bar"),或者为什么这是糟糕的编程实践。
发布于 2018-03-23 23:19:52
没有办法直接做你想做的事。
要理解为什么,您需要了解方法查找的工作方式。它在描述符HOWTO中得到了详细的解释,我试图编写一个不那么专家级别的解释这里,所以我假设您阅读了这两种解释,并展示了它们的效果:
>>> 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建议的那样,将fun2变成转发给fun2的property。或者你可以这么做:
def fun2(self):
return self.fun1()这个解决方案的好处是非常简单--任何会Python的人都会理解它的工作原理。
但是Patrick的解决方案的优点不仅仅是child().fun2(),还有child().fun2 (作为一个可以传递的对象,比较身份,等等)。按你想要的方式工作。
同时,有一个与您所要求的内容密切相关的成语,其中一组您不希望覆盖的公共方法称为您所做的“受保护”实现方法。例如,一个简单的一维数组-数学类可能会这样做:
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__之间没有不对称,只有“公共”接口(__add__和__radd__)和“受保护的”接口(_math)之间不对称。
发布于 2018-03-24 01:24:37
这里有一个非常简单的方法--这是完全可以的:
class Parent:
def fun1(self):
print("foo")
def fun2(self):
return self.fun1()
class Child(Parent):
def fun1(self):
print("bar")
Child().fun2() # -> bar发布于 2018-03-23 23:11:35
可以让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()
# barhttps://stackoverflow.com/questions/49459370
复制相似问题