在Python中创建简单的对象层次结构时,我希望能够从派生类调用父类的方法。在Perl和Java中,对此有一个关键字(super)。在Perl中,我可以这样做:

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
   my $str = SUPER::frotz();
   return uc($str);
}

在Python中,似乎我必须显式地从子类中命名父类。 在上面的例子中,我必须做一些类似于Foo::frotz()的事情。

这似乎是不正确的,因为这种行为使得很难建立深层的等级制度。如果孩子们需要知道哪个类定义了一个继承的方法,那么就会产生各种各样的信息麻烦。

这是python的实际限制,还是我理解上的差距,或者两者兼而有之?


当前回答

在Python 2中,我使用super()时运气不太好。我用的答案是 jimifiki在这个SO线程上如何引用python中的父方法? 然后,我添加了我自己的小改动,我认为这在可用性方面是一个改进(特别是如果您有很长的类名)。

在一个模块中定义基类:

 # myA.py

class A():     
    def foo( self ):
        print "foo"

然后导入类到另一个模块作为父模块:

# myB.py

from myA import A as parent

class B( parent ):
    def foo( self ):
        parent.foo( self )   # calls 'A.foo()'

其他回答

下面是一个使用super()的例子:

#New-style classes inherit from object, or from another new-style class
class Dog(object):

    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self):
        self.moves.append('walk')
        self.moves.append('run')

    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super(Superdog, self).moves_setup()
        self.moves.append('fly')

dog = Superdog('Freddy')
print dog.name # Freddy
dog.moves_setup()
print dog.get_moves() # ['walk', 'run', 'fly']. 
#As you can see our Superdog has all moves defined in the base Dog class

在python中也有一个super()。

如何从子类方法调用父类方法的示例

class Dog(object):
    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self,x):
        self.moves.append('walk')
        self.moves.append('run')
        self.moves.append(x)
    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super().moves_setup("hello world")
        self.moves.append('fly')
dog = Superdog('Freddy')
print (dog.name)
dog.moves_setup()
print (dog.get_moves()) 

这个例子类似于上面解释的例子。但是有一个区别,super没有传递任何参数给它。以上代码在python 3.4版本中可执行。

Python中也有一个super()。它有点不稳定,因为Python有新旧风格的类,但它非常常用,例如在构造函数中:

class Foo(Bar):
    def __init__(self):
        super(Foo, self).__init__()
        self.baz = 5

这是一个更抽象的方法:

super(self.__class__,self).baz(arg)

Python 3有一个不同的更简单的语法来调用父方法。

如果Foo类继承自Bar,则继承自Bar。__init__可以通过super()从Foo调用。__init__():

class Foo(Bar):

    def __init__(self, *args, **kwargs):
        # invoke Bar.__init__
        super().__init__(*args, **kwargs)