从继承层次中的顶层类调用方法而不是重写

2 投票
3 回答
1627 浏览
提问于 2025-04-16 16:54

假设我有两个类,Base(object)Derived(Base)。这两个类都有一个叫foo的函数,其中Derived.foo是对Basefoo的重写。

但是在Base的一个方法,比如Base.learn_to_foo中,我想调用Base.foo,而不是重写后的版本。不管重写与否,我都想用Base.foo(self)来调用它:

class Base(object):
    # ...

    def learn_to_foo(self, x):
        y = Base.foo(self, x)
        # check if we foo'd correctly, do interesting stuff

这种做法看起来是可行的,从逻辑上讲也很合理,但总觉得有点不太对劲。这种做法可以吗,还是说我应该重新考虑一下?

3 个回答

1

另一种方法是使用内置的'super'。

super(Derived, self).foo(x)     # Python 2

super().foo(x)                  # Python 3
2

建议使用:

def learn_to_foo(self, x):
  super(Derived, self).foo(x)

更多信息请访问 http://docs.python.org/library/functions.html#super

3

答案是不要使用super()这个函数。你现在的做法是完全正确的,因为你不想调用在父类中被重写的虚拟方法。看起来你总是想要基类的确切实现,唯一的方法就是获取基类的未绑定方法对象,然后将它绑定到self上,self可以是Base类或Derived类的一个实例。然后用self作为第一个参数来调用这个未绑定的方法,这样就会得到一个绑定的方法。从这一点开始,Base.foo就会作用于实例self的数据。这是完全可以接受的,也是Python处理非虚拟方法调用的方式。这是Python允许你做的一件很不错的事情,而Java就做不到。

撰写回答