我想通过Python中的子类对象调用在子类中被覆盖的父类方法

Posted

技术标签:

【中文标题】我想通过Python中的子类对象调用在子类中被覆盖的父类方法【英文标题】:I want to call parent class method which is overridden in child class through child class object in Python 【发布时间】:2020-10-21 18:11:49 【问题描述】:
class abc():
    def xyz(self):
        print("Class abc")

class foo(abc):
    def xyz(self):
        print("class foo")

x = foo()

我想调用父类的 xyz(),比如;

x.super().xyz()

【问题讨论】:

【参考方案1】:

对于像这样的单继承,我认为通过类调用方法并显式传递self 是最简单的:

abc.xyz(x)

使用super 更通用,这将变成(虽然我想不出一个好的用例):

super(type(x), x).xyz()

它返回一个超级对象,它可以被认为是父类,但子类是self

如果您想要与您的语法完全相同的东西,只需为您的类提供一个超级方法(您的abc 类,因此每个继承者都会拥有它):

def super(self):
    return super(type(self), self)

现在x.super().xyz() 可以工作了。如果你创建一个继承自 foo 的类,它会中断,因为你只能上一层(即回到 foo)。

据我所知,没有“通过对象”的方式来访问隐藏方法。

只是为了好玩,这里有一个更强大的版本,允许使用跟踪 super 调用的专用类链接超级调用:

class Super:
    def __init__(self, obj, counter=0):
        self.obj = obj
        self.counter = counter

    def super(self):
        return Super(self.obj, self.counter+1)

    def __getattr__(self, att):
        return getattr(super(type(self.obj).mro()[self.counter], self.obj), att)


class abc():
    def xyz(self):
        print("Class abc", type(self))

    def super(self):
        return Super(self)


class foo(abc):
    def xyz(self):
        print("class foo")


class buzz(foo):
    def xyz(self):
        print("class buzz")


buzz().super().xyz()
buzz().super().super().xyz()

结果

class foo
Class abc

【讨论】:

是的,但我这里的目标是通过对象调用方法。也必须有某种方法。感谢您的快速回复 @SyedFasih 你是什么意思?您希望x.super() 像您的示例一样工作吗?否则,据我所知,不,你错了。 super 是用于此目的的内置方法,不是对象的一部分。 您能否解释一下super(type(self), self) 的真正含义。这将非常有帮助。 “使用 super 更通用”在这里实际上可能不是一件好事。最可能的情况是这个调用站点想要调用一个特定的实现,而不是调用站点想要跳过任何存在于x 的派生类中的任何实现。 @user2357112supportsMonica 我同意你的看法。

以上是关于我想通过Python中的子类对象调用在子类中被覆盖的父类方法的主要内容,如果未能解决你的问题,请参考以下文章

在子类中,若要调用父类中被覆盖的方法,可以使用super关键字

多态的意义(四十二)

python子类调用父类的方法

dojo中类的继承

第49课 多态的概念和意义

继承多态