繁体   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