2024-04-26 08:09:32 发布
网友
class parent: def fun1(self): print("foo") fun2 = fun1 class child(parent): def fun1(self): print("bar") child().fun2()
此代码输出“foo”。我很确定我理解为什么会发生这种情况,但我想知道是否有一种简单的方法来实现我想要的(可继承的别名根据MRO的行为,所以它会输出“bar”),或者这是一种糟糕的编程实践的原因。你知道吗
可以将fun2作为返回self.fun1的属性
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
没有办法直接做你想做的事。你知道吗
要了解原因,您需要了解方法查找的工作方式。它在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。你知道吗
child.fun2
parent.fun1
child.fun1
child().fun2
self
child
child.__dict__
parent.__dict__
那么,解决办法是什么?你知道吗
你可以把fun2变成一个property转发给fun2,就像Patrick Haugh建议的那样。或者你可以这样做:
property
def fun2(self): return self.fun1()
这个解决方案的好处是非常简单,任何懂Python的人都会理解它的工作原理。你知道吗
但是Patrick的解决方案有一个优点,那就是不仅使child().fun2(),而且使child().fun2(作为一个可以传递、比较身份等的对象)按您希望的方式工作。你知道吗
child().fun2()
同时,还有一个与您所要求的内容密切相关的习惯用法,您不希望覆盖的一组公共方法调用您所做的“受保护”实现方法。例如,一个简单的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__之间没有不对称,只有在“公共”接口(__add__和__radd__)和“受保护”接口(_math)之间。你知道吗
__add__
__radd__
_math
这里有一个非常简单的方法,完全可以:
class Parent: def fun1(self): print("foo") def fun2(self): return self.fun1() class Child(Parent): def fun1(self): print("bar") Child().fun2() # -> bar
可以将
fun2
作为返回self.fun1
的属性没有办法直接做你想做的事。你知道吗
要了解原因,您需要了解方法查找的工作方式。它在the Descriptor HOWTO中有详细的解释,我试着写一个不太专业的解释here,所以我假设你读了这两个,并且只显示效果:
注意,
child.fun2
是parent.fun1
,而不是child.fun1
。这解释了为什么child().fun2
最终成为parent.fun1
周围的绑定方法,即使self
最终成为child
实例。为什么?很明显,fun2
不在child.__dict__
(或者我们不需要MRO)。在parent.__dict__
中,它只能是parent.fun1
。你知道吗那么,解决办法是什么?你知道吗
你可以把
fun2
变成一个property
转发给fun2
,就像Patrick Haugh建议的那样。或者你可以这样做:这个解决方案的好处是非常简单,任何懂Python的人都会理解它的工作原理。你知道吗
但是Patrick的解决方案有一个优点,那就是不仅使
child().fun2()
,而且使child().fun2
(作为一个可以传递、比较身份等的对象)按您希望的方式工作。你知道吗同时,还有一个与您所要求的内容密切相关的习惯用法,您不希望覆盖的一组公共方法调用您所做的“受保护”实现方法。例如,一个简单的1D数组数学类可能会执行以下操作:
现在在
__add__
和__radd__
之间没有不对称,只有在“公共”接口(__add__
和__radd__
)和“受保护”接口(_math
)之间。你知道吗这里有一个非常简单的方法,完全可以:
相关问题 更多 >
编程相关推荐