在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中的实际限制,我理解的差距还是两者兼而有之?

有帮助吗?

解决方案

是的,但仅适用于新式课程。使用 super() 功能:

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

对于Python 3.x,您可以使用:

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

其他提示

Python也有超级

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()
ImmediateParentClass.frotz(self)

会很好,无论是直接父类定义 frotz 本身还是继承它。 super 仅在正确支持多个继承时才需要(然后只有在每个类正确使用它时才有效)。通常, AnyClass.whatever 将在 AnyClass 的祖先中查找 ,如果 AnyClass 不定义/覆盖它,这适用于“子类调用父方法”至于任何其他事件!

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

如果 Foo 类继承自 Bar ,那么从 Bar .__ init __ 可以从 Foo 通过<代码>超级().__ INIT __()

class Foo(Bar):

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

许多答案解释了如何从已在孩子中覆盖的父级调用方法。

然而

  

“如何从子类调用父类的方法?”

也可能只是意味着:

  

“如何调用继承的方法?”

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

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 有助于理解如何访问继承的方法。

以下是使用 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()。由于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()

如果您不知道可能会得到多少参数,并希望将它们全部传递给孩子:

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中也有一个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 2中,我对super()没有太多运气。我用过的答案 这个SO线程上的jimifiki 如何在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()'

在此示例中,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

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()
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归因
不隶属于 StackOverflow
scroll top