Appeler la méthode d'une classe parent de la classe enfant en Python?
lors de la création d'une simple hiérarchie d'objets en Python, j'aimerais pouvoir invoquer les méthodes de la classe mère à partir d'une classe dérivée. En Perl et Java, il y a un mot clé pour ceci ( super
). En Perl, je pourrais faire ceci:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
en python, il semble que je doive nommer la classe parent explicitement à partir de l'enfant.
Dans l'exemple ci-dessus, je devrais faire quelque chose comme Foo::frotz()
.
This ne semble pas juste, car ce comportement rend difficile les grandes hiérarchies. Si les enfants ont besoin de savoir quelle classe définit une méthode héritée, puis toutes sortes d'informations douleur est créé.
est-ce une limitation réelle en python, une lacune dans ma compréhension ou les deux?
13 réponses
Oui, mais seulement avec nouveau style de classes . Utilisez la super()
fonction:
class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
Python a aussi super ainsi:
super(type[, object-or-type])
renvoie un objet de procuration qui délègue les appels de méthode à une classe de type de parent ou de frère ou sœur. Ceci est utile pour accéder aux méthodes héritées qui ont été dépassées dans une classe. L'ordre de recherche est le même que celui utilisé par getattr (), sauf que le type lui-même est ignorée.
exemple:
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)
sera très bien, que la classe de parent immédiate défini frotz
elle-même ou héritée. super
est seulement nécessaire pour le soutien approprié de héritage multiple (et alors il ne fonctionne que si chaque classe l'utilise correctement). En général, AnyClass.whatever
va chercher whatever
dans AnyClass
's ancêtres si AnyClass
ne définit pas / override it, et cela vaut pour "child class calling parent's method" comme pour toute autre événement!
Python 3 a une syntaxe différente et plus simple pour appeler la méthode parent.
Si la classe Foo
hérite de Bar
, alors la classe Bar.__init__
peut être invoquée de Foo
en utilisant super().__init__()
:
class Foo(Bar):
def __init__(self):
super().__init__()
voici un exemple d'utilisation de 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
beaucoup de réponses ont expliqué comment appeler une méthode du parent qui a été dépassé dans l'enfant.
cependant
" comment appelez-vous la méthode de la classe des parents de la classe des enfants?"
pourrait aussi signifier:
"comment appelez-vous les méthodes héritées?"
vous pouvez appeler des méthodes héritées d'une classe parent juste comme s'ils étaient des méthodes de la classe enfant, tant qu'ils n'ont pas été écrasés.
p.ex. en 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"
Oui, cela peut être assez évident, mais je pense que sans souligner cela, les gens peuvent laisser ce fil avec l'impression que vous devez sauter à travers des cerceaux ridicules juste pour accéder aux méthodes héritées en python. D'autant plus que cette question est très importante dans les recherches de "comment accéder à la méthode d'une classe mère en Python", et OP est écrit du point de vue de quelqu'un de nouveau en python.
j'ai trouvé: https://docs.python.org/3/tutorial/classes.html#inheritance être utile pour comprendre comment vous accédez aux méthodes héritées.
il y a un super() en Python aussi. C'est un peu compliqué, à cause des anciennes et des nouvelles classes de Python, mais il est assez couramment utilisé, par exemple dans les constructeurs:
class Foo(Bar):
def __init__(self):
super(Foo, self).__init__()
self.baz = 5
je recommande d'utiliser CLASS.__bases__
quelque chose comme ça
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()
si vous ne savez pas combien d'arguments vous pourriez avoir, et que vous voulez les transmettre à l'enfant aussi bien:
class Foo(bar)
def baz(self, arg, *args, **kwargs):
# ... Do your thing
return super(Foo, self).baz(arg, *args, **kwargs)
(à Partir de: Python - façon la plus Propre à remplacer __init__, où une option de kwarg doit être utilisé après l'appel super ()? )
il y a aussi un super() en python.
exemple pour la façon dont une méthode de super classe est appelée à partir d'une méthode de sous-classe
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())
cet exemple est similaire à celui expliqué ci-dessus.Il existe cependant une différence que super n'ont pas d'arguments transmis.Ce code ci-dessus est exécutable en version Python 3.4.
en Python 2, Je n'ai pas eu beaucoup de chance avec super(). J'ai utilisé la réponse de jimifiki sur ce fil SO comment se référer à une méthode parent en python? . Puis, j'y ai ajouté ma propre petite touche, ce qui, je pense, est une amélioration de la convivialité (surtout si vous avez de longs noms de classe).
définit la classe de base dans un module:
# myA.py
class A():
def foo( self ):
print "foo"
puis importer la classe dans un autre module as parent
:
# myB.py
from myA import A as parent
class B( parent ):
def foo( self ):
parent.foo( self ) # calls 'A.foo()'
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()
c'est une méthode plus abstraite:
super(self.__class__,self).baz(arg)