Rufen Sie eine Methode der übergeordneten Klasse von untergeordneter Klasse in Python?
-
03-07-2019 - |
Frage
Wenn Sie eine einfache Objekthierarchie in Python zu schaffen, würde Ich mag zu können, Methoden der Elternklasse aus einer abgeleiteten Klasse aufzurufen. In Perl und Java gibt es ein Schlüsselwort für diese ( super
). In Perl, könnte ich dies tun:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
In Python, scheint es, dass ich hiermit ausdrücklich von dem Kind der übergeordnete Klasse nennen.
In dem obigen Beispiel würde, ich habe so etwas wie Foo::frotz()
zu tun.
Dies scheint nicht richtig, da dieses Verhalten ist es schwer zu machen tiefe Hierarchien macht. Wenn Kinder wissen müssen, welche Klasse eine geerbte Methode definiert, dann werden alle Arten von Informationen Schmerz erzeugt.
Ist dies eine tatsächliche Einschränkung in Python, eine Lücke in meinem Verständnis oder beides?
Lösung
Ja, aber nur mit neuen Stil Klassen . Verwenden Sie die super()
Funktion:
class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
Für Python 3.x können Sie verwenden:
class Foo(Bar):
def baz(self, arg):
return super().baz(arg)
Andere Tipps
Python hat auch Super auch:
super(type[, object-or-type])
Gibt ein Proxy-Objekt, dass die Delegierten Methodenaufrufe an einen Elternteil oder Geschwister Klasse des Typs. Dies ist nützlich für geerbte Methoden zugreifen, die in einer Klasse überschrieben wurden. Die Suchreihenfolge ist die gleiche wie die von getattr () verwendet, außer dass der Typ selbst übersprungen wird.
Beispiel:
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)
wird gut sein, ob die unmittelbar übergeordnete Klasse definierte frotz
selbst oder geerbt. super
ist nur erforderlich für die richtige Unterstützung von mehrere Erbe (und nur dann funktioniert, wenn jede Klasse es richtig verwendet). Im Allgemeinen wird AnyClass.whatever
whatever
in AnyClass
Vorfahren suchen, wenn AnyClass
es nicht definieren / außer Kraft setzen, und dies gilt für „Kind Klasse Eltern Methode aufrufen“ wie bei jedem anderen Vorkommen!
Python 3 hat eine andere und einfachere Syntax für Eltern Methode aufrufen.
Wenn Foo
Klasse von Bar
erbt, dann von Bar.__init__
aus Foo
über super().__init__()
aufgerufen werden:
class Foo(Bar):
def __init__(self, *args, **kwargs):
# invoke Bar.__init__
super().__init__(*args, **kwargs)
Viele Antworten haben erklärt, wie ein Verfahren, von dem Elternteil nennen, die in dem Kind außer Kraft gesetzt worden ist.
Allerdings
„Wie nennt man eine Methode der übergeordneten Klasse von Kind Klasse?“
könnte auch nur bedeuten:
„Wie nennt man geerbten Methoden?“
Sie können Methoden von einer übergeordneten Klasse geerbt nennen, als ob sie Methoden des Kindes Klasse waren, solange sie nicht überschrieben wurden.
z. in 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"
ja, kann dies ziemlich offensichtlich sein, aber ich fühle, dass dies ohne den Hinweis auf Menschen mit dem Eindruck dieses Thema verlassen können Sie einfach lächerlich Reifen springen müssen durch geerbte Methoden in Python zugreifen. Vor allem, da diese Frage Raten hoch bei der Suche nach „wie eine Elternklasse Methode in Python zugreifen“, und die OP wird aus der Perspektive von jemandem geschrieben neu zu Python.
Ich fand: https://docs.python.org/3/tutorial/classes.html#inheritance nützlich zu sein, zu verstehen, wie Sie geerbte Methoden zugreifen.
Hier ist ein Beispiel für die Verwendung 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
Es gibt eine super () auch in Python. Es ist ein bisschen wackelig, weil der Python Old- und New-Style-Klassen, aber recht häufig verwendet wird, z.B. in Bauer:
class Foo(Bar):
def __init__(self):
super(Foo, self).__init__()
self.baz = 5
Ich würde empfehlen, CLASS.__bases__
mit
so etwas wie diese
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()
Wenn Sie nicht wissen, wie viele Argumente, die Sie vielleicht bekommen, und wollen sie alle durch, um das Kind passieren, wie gut:
class Foo(bar)
def baz(self, arg, *args, **kwargs):
# ... Do your thing
return super(Foo, self).baz(arg, *args, **kwargs)
Es ist ein super () in Python auch.
Beispiel dafür, wie eine Super-Klasse-Methode aus einer Unterklasse Methode aufgerufen wird,
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())
Dieses Beispiel ist ähnlich wie derjenige erklärt above.However gibt es einen Unterschied, dass Super keine Argumente it.This obigen Code ausführbar ist in Python 3.4 Version bestanden hat.
In Python 2, ich habe nicht viel Glück mit Super habe (). Früher habe ich die Antwort aus jimifiki auf das so fädelt , wie an ein übergeordneten Verfahren, in Python verweisen ? . Dann fügte ich meine eigene kleine Wendung es, was ich denke, ist eine Verbesserung der Benutzerfreundlichkeit (Vor allem, wenn man lange Klassennamen hat).
Definieren Sie die Basisklasse in einem Modul:
# myA.py
class A():
def foo( self ):
print "foo"
Dann die Klasse in einer anderen Module as parent
importieren:
# myB.py
from myA import A as parent
class B( parent ):
def foo( self ):
parent.foo( self ) # calls 'A.foo()'
in diesem Beispiel cafec_param ist eine Basisklasse (Elternklasse) und abc ist ein Kind Klasse. abc ruft die AWC-Methode in der Basisklasse.
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
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()
Dies ist eine abstrakte Methode:
super(self.__class__,self).baz(arg)