[英]How do I call a parent class's method from a child class in Python?
When creating a simple object hierarchy in Python, I'd like to be able to invoke methods of the parent class from a derived class.在 Python 中创建简单的对象层次结构时,我希望能够从派生类调用父类的方法。 In Perl and Java, there is a keyword for this (
super
).在 Perl 和 Java 中,有一个关键字(
super
)。 In Perl, I might do this:在 Perl 中,我可能会这样做:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
In Python, it appears that I have to name the parent class explicitly from the child.在 Python 中,似乎我必须从子类中显式命名父类。 In the example above, I'd have to do something like
Foo::frotz()
.在上面的示例中,我必须执行类似
Foo::frotz()
的操作。
This doesn't seem right since this behavior makes it hard to make deep hierarchies.这似乎不正确,因为这种行为使得很难建立深层层次结构。 If children need to know what class defined an inherited method, then all sorts of information pain is created.
如果孩子需要知道什么类定义了一个继承的方法,那么就会产生各种信息的痛苦。
Is this an actual limitation in python, a gap in my understanding or both?这是python的实际限制,我理解的差距还是两者兼而有之?
Use the super()
function:使用
super()
函数:
class Foo(Bar):
def baz(self, arg):
return super().baz(arg)
For Python < 3, you must explicitly opt in to using new-style classes and use:对于 Python < 3,您必须明确选择使用新式类并使用:
class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
Python also has super as well: Python 也有super :
super (type[, object-or-type])
Return a proxy object that delegates method calls to a parent or sibling class of type.
返回一个代理对象,该对象将方法调用委托给类型的父类或兄弟类。 This is useful for accessing inherited methods that have been overridden in a class.
这对于访问在类中被覆盖的继承方法很有用。 The search order is same as that used by getattr() except that the type itself is skipped.
搜索顺序与 getattr() 使用的相同,只是跳过了类型本身。
Example:例子:
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)
will be just fine, whether the immediate parent class defined frotz
itself or inherited it.会很好,无论直接父类是定义
frotz
本身还是继承它。 super
is only needed for proper support of multiple inheritance (and then it only works if every class uses it properly). super
只需要正确支持多重继承(然后它只有在每个类都正确使用它时才有效)。 In general, AnyClass.whatever
is going to look up whatever
in AnyClass
's ancestors if AnyClass
doesn't define/override it, and this holds true for "child class calling parent's method" as for any other occurrence!一般来说,如果
AnyClass
没有定义/覆盖它, AnyClass.whatever
将在AnyClass
的祖先中查找whatever
内容,这对于“调用父类方法的子类”以及任何其他事件都适用!
Python 3 has a different and simpler syntax for calling parent method. Python 3有一种不同且更简单的语法来调用父方法。
If Foo
class inherits from Bar
, then from Bar.__init__
can be invoked from Foo
via super().__init__()
:如果
Foo
类继承自Bar
,则可以通过super().__init__()
从Foo
调用来自Bar.__init__
:
class Foo(Bar):
def __init__(self, *args, **kwargs):
# invoke Bar.__init__
super().__init__(*args, **kwargs)
Many answers have explained how to call a method from the parent which has been overridden in the child.许多答案已经解释了如何从父级调用已在子级中被覆盖的方法。
However然而
"how do you call a parent class's method from child class?"
“你如何从子类调用父类的方法?”
could also just mean:也可能只是意味着:
"how do you call inherited methods?"
“你如何调用继承的方法?”
You can call methods inherited from a parent class just as if they were methods of the child class, as long as they haven't been overwritten.您可以调用从父类继承的方法,就像它们是子类的方法一样,只要它们没有被覆盖。
eg in python 3:例如在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"
yes, this may be fairly obvious, but I feel that without pointing this out people may leave this thread with the impression you have to jump through ridiculous hoops just to access inherited methods in python.是的,这可能是相当明显的,但我觉得如果不指出这一点,人们可能会给这个帖子留下这样的印象:你必须跳过荒谬的圈套才能访问 python 中的继承方法。 Especially as this question rates highly in searches for "how to access a parent class's method in Python", and the OP is written from the perspective of someone new to python.
特别是因为这个问题在“如何访问 Python 中的父类方法”的搜索中得分很高,并且 OP 是从 Python 新手的角度编写的。
I found: https://docs.python.org/3/tutorial/classes.html#inheritance to be useful in understanding how you access inherited methods.我发现: https : //docs.python.org/3/tutorial/classes.html#inheritance有助于理解如何访问继承的方法。
Here is an example of using super() :下面是一个使用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
There's a super() in Python too. Python 中也有一个 super() 。 It's a bit wonky, because of Python's old- and new-style classes, but is quite commonly used eg in constructors:
由于 Python 的旧式和新式类,这有点不稳定,但在构造函数中非常常用:
class Foo(Bar):
def __init__(self):
super(Foo, self).__init__()
self.baz = 5
I would recommend using CLASS.__bases__
something like this我建议使用
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()
If you don't know how many arguments you might get, and want to pass them all through to the child as well:如果您不知道可能会收到多少个参数,并且还想将它们全部传递给孩子:
class Foo(bar)
def baz(self, arg, *args, **kwargs):
# ... Do your thing
return super(Foo, self).baz(arg, *args, **kwargs)
(From: Python - Cleanest way to override __init__ where an optional kwarg must be used after the super() call? ) (来自: Python - 覆盖 __init__ 的最简洁方法,其中在 super() 调用之后必须使用可选的 kwarg? )
There is a super() in python also. python 中也有一个 super() 。
Example for how a super class method is called from a sub class method如何从子类方法调用超类方法的示例
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())
This example is similar to the one explained above.However there is one difference that super doesn't have any arguments passed to it.This above code is executable in python 3.4 version.这个例子类似于上面解释的那个。但是有一个区别是 super 没有任何参数传递给它。上面的代码在 python 3.4 版本中是可执行的。
In this example cafec_param
is a base class (parent class) and abc
is a child class.在这个例子中,
cafec_param
是一个基类(父类), abc
是一个子类。 abc
calls the AWC
method in the base class. 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())
Output输出
56
56
56
In Python 2, I didn't have a lot luck with super().在 Python 2 中,我对 super() 的运气并不好。 I used the answer from jimifiki on this SO thread how to refer to a parent method in python?
我在这个 SO 线程上使用了 jimifiki 的答案如何在 python 中引用父方法? .
. Then, I added my own little twist to it, which I think is an improvement in usability (Especially if you have long class names).
然后,我添加了我自己的小改动,我认为这是可用性的改进(特别是如果你有很长的类名)。
Define the base class in one module:在一个模块中定义基类:
# myA.py
class A():
def foo( self ):
print "foo"
Then import the class into another modules as parent
:然后将该类
as parent
模块导入另一个模块:
# myB.py
from myA import A as parent
class B( parent ):
def foo( self ):
parent.foo( self ) # calls 'A.foo()'
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()
If you want to call the method of any class, you can simply call Class.method
on any instance of the class.如果要调用任何类的方法,只需在该类的任何实例上调用
Class.method
即可。 If your inheritance is relatively clean, this will work on instances of a child class too:如果您的继承相对干净,这也适用于子类的实例:
class Foo:
def __init__(self, var):
self.var = var
def baz(self):
return self.var
class Bar(Foo):
pass
bar = Bar(1)
assert Foo.baz(bar) == 1
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()
这是一个更抽象的方法:
super(self.__class__,self).baz(arg)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.