在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中的实际限制,我理解的差距还是两者兼而有之?
答案 0 :(得分:599)
是的,但仅限于new-style classes。使用super()
功能:
class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
答案 1 :(得分:125)
Python也有super:
super(type[, object-or-type])
返回一个代理对象,该方法将方法调用委托给父类或兄弟类类型。 这对于访问已在类中重写的继承方法很有用。 搜索顺序与getattr()使用的搜索顺序相同,只是跳过了类型本身。
示例:
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()
答案 2 :(得分:78)
ImmediateParentClass.frotz(self)
无论直接父类是自定义frotz
还是继承它,都可以。 super
只需要正确支持多个继承(然后只有在每个类都正确使用它时才有效)。一般来说,如果AnyClass.whatever
没有定义/覆盖它,whatever
将在AnyClass
的祖先中查找AnyClass
,这适用于“子类调用父母的方法“就任何其他事件而言!
答案 3 :(得分:62)
Python 3 有一种不同且更简单的语法来调用父方法。
如果Foo
类继承自Bar
,那么Bar.__init__
可以从Foo
通过super().__init__()
调用:
class Foo(Bar):
def __init__(self, *args, **kwargs):
# invoke Bar.__init__
super().__init__(*args, **kwargs)
答案 4 :(得分:33)
许多答案解释了如何从已在孩子中覆盖的父级调用方法。
然而
"你如何从子类中调用父类的方法?"
也可能只是意味着:
"你如何称呼继承方法?"
您可以调用从父类继承的方法,就像它们是子类的方法一样,只要它们没有被覆盖。
e.g。在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中的继承方法。特别是因为这个问题在搜索"如何在Python"中访问父类的方法时得到高度评价,并且OP是从对python的新人的角度编写的。
我发现: https://docs.python.org/3/tutorial/classes.html#inheritance 有助于理解如何访问继承的方法。
答案 5 :(得分:26)
以下是使用 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
答案 6 :(得分:13)
Python中也有一个super()。由于Python的旧式和新式类,它有点不稳定,但是很常用,例如在构造函数中:
class Foo(Bar):
def __init__(self):
super(Foo, self).__init__()
self.baz = 5
答案 7 :(得分:9)
我建议使用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()
答案 8 :(得分:6)
如果你不知道你可能会得到多少论点,并希望将它们全部传递给孩子:
class Foo(bar)
def baz(self, arg, *args, **kwargs):
# ... Do your thing
return super(Foo, self).baz(arg, *args, **kwargs)
答案 9 :(得分:4)
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版本中执行。
答案 10 :(得分:1)
在Python 2中,我对super()没有太多运气。我用过的答案 这个SO线程how to refer to a parent method in python?上的jimifiki。 然后,我添加了自己的小麻烦,我认为这是一个可用性的改进(特别是如果你有长名字)。
在一个模块中定义基类:
# myA.py
class A():
def foo( self ):
print "foo"
然后将该类导入另一个模块as parent
:
# myB.py
from myA import A as parent
class B( parent ):
def foo( self ):
parent.foo( self ) # calls 'A.foo()'
答案 11 :(得分:1)
在此示例中,cafec_param是基类(父类),而abc是子类。 abc在基类中调用AWC方法。
class cafec_param:
def __init__(self,precip,pe,awc,nmonths):
self.precip = precip
self.pe = pe
self.awc = awc
self.nmonths = nmonths
def AWC(self):
if self.awc<254:
Ss = self.awc
Su = 0
self.Ss=Ss
else:
Ss = 254; Su = self.awc-254
self.Ss=Ss + Su
AWC = Ss + Su
return self.Ss
def test(self):
return self.Ss
#return self.Ss*4
class abc(cafec_param):
def rr(self):
return self.AWC()
ee=cafec_param('re',34,56,2)
dd=abc('re',34,56,2)
print(dd.rr())
print(ee.AWC())
print(ee.test())
输出
56
56
56
答案 12 :(得分:0)
class department:
campus_name="attock"
def printer(self):
print(self.campus_name)
class CS_dept(department):
def overr_CS(self):
department.printer(self)
print("i am child class1")
c=CS_dept()
c.overr_CS()
答案 13 :(得分:-3)
class a(object):
def my_hello(self):
print "hello ravi"
class b(a):
def my_hello(self):
super(b,self).my_hello()
print "hi"
obj = b()
obj.my_hello()
答案 14 :(得分:-22)
这是一种更抽象的方法:
super(self.__class__,self).baz(arg)