为什么,在父类上使用self调用函数时,子类实际上是在Python中运行的
我有两个抽象类,定义如下:为什么,在父类上使用self调用函数时,子类实际上是在Python中运行的,python,python-3.x,multiple-inheritance,Python,Python 3.x,Multiple Inheritance,我有两个抽象类,定义如下: from abc import ABC, abstractmethod class A(ABC): def __init__(self, lst): self.List = lst @abstractmethod def __enter__(self) -> 'Component': return self @abstractmethod def __exit__(self, *ex
from abc import ABC, abstractmethod
class A(ABC):
def __init__(self, lst):
self.List = lst
@abstractmethod
def __enter__(self) -> 'Component':
return self
@abstractmethod
def __exit__(self, *exc):
pass
class B(ABC):
def __init__(self, lst):
self.List = lst
@abstractmethod
def run(self):
pass
现在,我有了一个继承自以下内容的类:
class C(A, B):
def __init__(self, lst):
A.__init__(self, lst)
B.__init__(self, lst)
def __enter__(self) -> 'C':
self.List.append('C.__enter__')
self.run()
return self
def __exit__(self, *exc):
self.List.append('C.__exit__')
def run(self):
self.List.append('C.run')
最后,我有一个从C继承的类:
现在,我的代码如下所示:
my_d = D( ['start'] )
with my_d:
pass
print(my_d)
根据我对super工作原理的理解,这将产生以下结果:
[ start,
D.__enter__,
C.__enter__,
C.run,
C.__exit__,
D.__exit__ ]
但实际情况是:
[ start,
D.__enter__,
C.__enter__,
D.run,
C.run,
C.__exit__,
D.__exit__ ]
我在任何地方都没有显式地调用D.run,但却调用了D.run
这对我来说毫无意义,除非当我调用super时,self在D中输入,self认为它仍然在D中,而实际上在C中。有人能告诉我这一点吗?调用D.run时调用C.run:
与“退出”和“进入”相同
D.run从链D中调用。uuu enter_uuu->C.uu enter_uu现在调用self.run,由于self的类型是D,这将调用D.run->C.run
赛尔夫并不认为它是“在D里面”;赛尔夫属于D型
如果你想得到你想要的输出,你可以不重写在D中运行;这样,只调用C.run。调用D.run时调用C.run:
与“退出”和“进入”相同
D.run从链D中调用。uuu enter_uuu->C.uu enter_uu现在调用self.run,由于self的类型是D,这将调用D.run->C.run
赛尔夫并不认为它是“在D里面”;赛尔夫属于D型
如果你想得到你想要的输出,你可以不重写在D中运行;这样,只会调用C.run。def run in D会覆盖def run in C。因此,当您调用run in C.\uu enter\uuu时,它实际上会调用D.run。
当D.run被调用时,super.run调用C.run
当我第一次学习python类继承时,我同样感到困惑,但这就是它的工作原理。def run in D覆盖def run in C。因此,当您调用run in C.u enter_u时,它实际上调用D.run。
当D.run被调用时,super.run调用C.run
当我第一次学习python类继承时,我同样感到困惑,但它就是这样工作的。这并不能回答我的问题。从我提交的代码中可以看到,我没有显式地调用D.run。我叫D.uu enter,它叫C.u enter。然后C.。\uuuuuu输入调用self.run。你是说对self.run的呼叫是对D.run的呼叫吗?@Woody1193:为什么它会呼叫其他任何东西?好的,我理解你的答案。我该如何解决这个问题?这并不能回答我的问题。从我提交的代码中可以看到,我没有显式地调用D.run。我叫D.uu enter,它叫C.u enter。然后C.。\uuuuuu输入调用self.run。你是说对self.run的呼叫是对D.run的呼叫吗?@Woody1193:为什么它会呼叫其他任何东西?好的,我理解你的答案。我该怎么解决?赛尔夫不认为它在任何东西里面。自我只是一个变量。它包含对对象的引用。该对象的类型不会因为执行C方法而改变。self对象在类C中仍然是类D的引用。因此执行的函数是D.run而不是C.runself不认为它在任何东西中。自我只是一个变量。它包含对对象的引用。该对象的类型不会因为正在执行C方法而改变。当在类C内时,self对象仍然是类D的引用对象。因此执行的函数是D.run而不是C.run
[ start,
D.__enter__,
C.__enter__,
D.run,
C.run,
C.__exit__,
D.__exit__ ]
class D(C):
def run(self):
self.List.append('D.run')
super().run() # this will add 'C.run' to self.List