[英]Why, when calling a function with self on the parent class, the child class is actually run in Python
我有兩個具有以下定義的抽象類:
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
的類:
class D(C):
def __init__(self, lst):
super().__init__(lst)
def __enter__(self) -> 'D':
self.List.append('D.__enter__')
super().__enter__()
return self
def __exit__(self, *exc):
super().__exit__()
self.List.append('D.__exit__')
def run(self):
self.List.append('D.run')
super().run()
現在,我的代碼如下所示:
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
調用D.run
。
除非我在D中調用super().__enter__
,否則self
以某種方式認為它實際上在C
時仍在D
,這對我來說真的沒有意義。 有人可以啟發我嗎?
在調用C.run
時調用D.run
:
class D(C):
def run(self):
self.List.append('D.run')
super().run() # this will add 'C.run' to self.List
與__exit__
和__enter__
相同。
D.run
從鏈稱為D.__enter__
- > C.__enter__
現在調用self.run()
並作為self
具有type
D
這將調用D.run
- > C.run
)。
self
不認為這是“ D
內部”; self
是類型D
如果要獲得所需的輸出,則不能覆蓋在D
run
; 這樣,只會C.run
。
def run()
在d覆蓋def run()
所以C.當你調用run()
在C.__enter__
,它實際上調用D.run()
當D.run()
被稱為super().run()
調用C.run()
第一次學習python類繼承時,這同樣讓我感到困惑,但這就是它的工作方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.