在 Python 的超类中调用超类方法

Posted

技术标签:

【中文标题】在 Python 的超类中调用超类方法【英文标题】:Calling superclass method in superclass in Python 【发布时间】:2021-11-10 14:26:24 【问题描述】:

我从子类 (bazz1 = super().foo(raw=raw, arg2=arg2, **kwargs)) 调用超类方法。在超类方法中,我再次调用了其他超类方法 (return bazz1 if raw else self.process(bazz1))。

在执行期间发生的事情是我没有预料到的。我定义了SuperClassdef foo(...) 调用self.process(bazz1)。会发生什么而不是输入SuperClass.process(...),执行输入DerivedClass.process(...)。有没有办法明确防止这种情况发生?

class UltraClass(metaclass=ABCMeta):
    def __init__(self, arg1):
        super().__init__()

    @abc.abstractmethod
    def foo(self, **kwargs) -> bazz:
        pass

    @abc.abstractmethod
    def bar(self, arg1, **kwargs) -> bazz:
        pass


class SuperClass(UltraClass):
    def __init__(self, arg1):
        super().__init__(arg1)

    def foo(self, raw, **kwargs) -> bazz:
        ...
        bazz1 = get_bazz(...)
        return bazz1 if raw else self.process(bazz1)

    def process(self, bazz1, **kwargs) -> bazz:
        return bazz1

class DerivedClass(SuperClass):
    def __init__(self, arg1):
        super().__init__(arg1)

    def foo(self, raw, **kwargs) -> bazz:
        ...
        bazz1 = super().foo(raw=raw, arg2=arg2, **kwargs)
        return bazz1 if raw else self.process(bazz1)

    def process(self, bazz1, **kwargs) -> bazz:
        ...
        ...
        ...
        return bazz1

【问题讨论】:

您的声明What happens in the execution time is that subclass method is called. What would be the correct way to call superclass method? 不清楚。您能否详细说明您的意思。从哪里调用超类方法?你是如何在运行时调用函数的? 另外,在您的代码中,SuperClass 不会继承自另一个类。 bazz1从哪里来,让SuperClass.foo返回? 如果你的超类需要调用它自己版本的被覆盖的方法,那么你的类结构就有缺陷。你需要重新考虑你的设计。子类化的全部意义在于让子类处于控制之中。 【参考方案1】:

如果您希望基类调用某个方法的自己版本,您可以显式调用该类上的方法,手动传递self

class Base:
    def foo(self):
        pass

    def no_derivs(self):
        Base.foo(self)  # only ever call our own foo method, not any overriden version

但这很少是个好主意。通常,如果子类覆盖了一个方法,它会这样做是因为该方法需要以不同的方式表现,否则子类的逻辑将被破坏。如果该方法的基类版本可以工作,那么它一开始就不会被覆盖。

因此,正如 Tim Roberts 评论的那样,如果您认为需要这种行为,则表明您的类层次结构设计存在缺陷。派生类不应该覆盖某些基类方法,或者基类应该是调用这些方法的派生版本的内容(如果需要,可以通过super 调用方法的基版本)。

【讨论】:

以上是关于在 Python 的超类中调用超类方法的主要内容,如果未能解决你的问题,请参考以下文章

Java多态如何调用子类对象的超类方法

Object:所有类的超类

防止类在 Python 中直接实例化

是否可以在 C++ 中的超类中拥有子类的成员

使用返回超类对象的超类方法 - Java

是否可以在超类对象上调用子类的方法?