从Python中的子类调用父类的方法?

在Python中创build简单的对象层次结构时,我希望能够从派生类中调用父类的方法。 在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()。

这看起来不正确,因为这种行为使得很难做出深层次的结构。 如果孩子需要知道什么类定义了一个inheritance的方法,那么就会产生各种信息的痛苦。

这是python的一个实际的限制,在我的理解或两者的差距?

是的,但只有新式的课程 。 使用super()函数:

 class Foo(Bar): def baz(self, arg): return super(Foo, self).baz(arg) 

Python也有很好的function:

super (type[, object-or-type])

返回一个将方法调用委托给父类或兄弟类的代理对象。 这对访问在类中被覆盖的inheritance方法很有用。 search顺序与getattr()使用的顺序相同,只是跳过了types本身。

例:

 class A(object): # deriving from 'object' declares A as a 'new-style-class' def foo(self): print "foo" class B(A): def foo(self): super(B, self).foo() # calls 'A.foo()' myB = B() myB.foo() 
 ImmediateParentClass.frotz(self) 

将会很好,直接父类是否定义了frotz本身或inheritance它。 super只是为了适当的支持多重inheritance(然后它只适用于每个类都正确使用它)。 一般来说,如果AnyClass没有定义/覆盖AnyClassAnyClass.whatever将会在AnyClass的祖先中查找whatever ,对于任何其他情况,“子类调用父方法”也是如此。

这是一个使用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 3具有不同且更简单的语法。 如果Foo类inheritance自Bar ,那么从Bar.__init__可以使用super().__init__()Foo调用:

 class Foo(Bar): def __init__(self): super().__init__() 

Python中也有一个super()。 由于Python的旧式和新式类,这有点过分,但是在构造函数中是相当常用的:

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

我会推荐使用CLASS.__bases__这样的东西

 class A: def __init__(self): print "I am Class %s"%self.__class__.__name__ for parentClass in self.__class__.__bases__: print " I am inherited from:",parentClass.__name__ #parentClass.foo(self) <- call parents function with self as first param class B(A):pass class C(B):pass a,b,c = A(),B(),C() 

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没有任何parameter passing给它。上面的代码在Python 3.4版本中是可执行的。

许多答案已经解释了如何从父母中调用一个已被孩子覆盖的方法。

然而

“你怎么从小孩class级调用父class的方法?”

也可能只是意味着:

“你怎么称之为inheritance的方法?”

您可以调用从父类inheritance的方法,就像它们是子类的方法一样,只要它们没有被覆盖。

例如在python 3:

 class A(): def bar(self, string): print("Hi, I'm bar, inherited from A"+string) class B(A): def baz(self): self.bar(" - called by baz in B") B().baz() # prints out "Hi, I'm bar, inherited from A - called by baz in B" 

是的,这可能是相当明显的,但我觉得没有指出这一点,人们可能离开这个线程的印象,你必须跳过荒谬的箍,只是为了访问python中的inheritance方法。 特别是当这个问题在search“如何在Python中访问一个父类的方法”时高度评价,而OP是从一个新的pythonangular度编写的。

我发现: https : //docs.python.org/3/tutorial/classes.html#inheritance在理解如何访问inheritance的方法方面很有用。

如果你不知道你可能得到多less论点,并想把它们全部传给孩子:

 class Foo(bar) def baz(self, arg, *args, **kwargs): # ... Do your thing return super(Foo, self).baz(arg, *args, **kwargs) 

(来自: Python – 最好的方法来覆盖__init__在super()调用后必须使用可选的kwarg? )

在Python 2中,我没有运用super()。 我用这个SO线程从jimifiki的答案如何引用在Python中的父方法? 。 然后,我添加了自己的小小的转折,我认为这是对可用性的改进(特别是如果你有很长的类名)。

在一个模块中定义基类:

  # myA.py class A(): def foo( self ): print "foo" 

然后将该类as parent类导入到另一个模块as parent

 # myB.py from myA import A as parent class B( parent ): def foo( self ): parent.foo( self ) # calls 'A.foo()' 

这是一个更抽象的方法:

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