简体   繁体   English

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

[英]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.

相关问题 如何在Python的子类中调用和覆盖父类方法 - How to call and override a Parent class method from Child class in Python 如何在父类方法中调用子类方法? - How do I call a Child class method from within a Parent class Method? Python 如何从父元类调用子 class 方法 - Python How to call child class method from Parent metaclass 在Python 2中从子类调用父类方法 - Call a parent class method from a child class in Python 2 在Python中,有没有办法从其父类调用子类的方法覆盖? - In Python, is there any way to call a child class's method override from its parent class? 如何调用子 class 而不是父 class 方法的覆盖方法? - How do I call the overwritten method of the child class instead of the parent class method? 如何在子类中创建的字典中调用父类的方法? - How do you call a parent class's method within a dictionary created in the child class? 如何决定从父类或子类中调用子类中的重写方法? - How can I decide to call an overrided method in child class from either parent or child class? Python父类init调用子级的覆盖方法 - Python parent class init call child's overwritten method I want to call parent class method which is overridden in child class through child class object in Python - I want to call parent class method which is overridden in child class through child class object in Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM