簡體   English   中英

為什么在父類上調用帶有self的函數時,子類實際上在Python中運行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM