【问题标题】:Calling superclass method in superclass in Python在 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返回?
  • 如果你的超类需要调用它自己版本的被覆盖的方法,那么你的类结构就有缺陷。你需要重新考虑你的设计。子类化的全部意义在于让子类处于控制之中。

标签: python oop prototypal-inheritance python-class


【解决方案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 调用方法的基版本)。

【讨论】:

    猜你喜欢
    • 2012-12-30
    • 2011-03-02
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多