Question

Lors de la création d'une hiérarchie d'objet simple en Python, j'aimerais pouvoir appeler les méthodes de la classe parente à partir d'une classe dérivée. En Perl et Java, il existe un mot clé pour cela ( 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 apparaît que je dois nommer explicitement la classe parent à partir de l'enfant. Dans l'exemple ci-dessus, je devrais faire quelque chose comme Foo :: frotz () .

Cela ne semble pas correct, car ce comportement rend difficile la création de hiérarchies profondes. Si les enfants ont besoin de savoir quelle classe a défini une méthode héritée, toutes sortes d'informations douloureuses sont créées.

S'agit-il d'une limitation réelle en python, d'une lacune dans ma compréhension ou des deux?

Était-ce utile?

La solution

Oui, mais uniquement avec les classes de style nouveau . Utilisez la fonction super () :

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

Pour Python 3.x, vous pouvez utiliser:

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

Autres conseils

Python possède également super :

super (type [, objet ou type])

  

Renvoie un objet proxy qui délègue des appels de méthode à une classe de type parent ou sœur.   Ceci est utile pour accéder aux méthodes héritées qui ont été remplacées dans une classe.   L'ordre de recherche est identique à celui utilisé par getattr (), sauf que le type lui-même est ignoré.

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)

ira très bien, que la classe parente immédiate ait défini frotz elle-même ou qu’elle en ait hérité. super n'est nécessaire que pour la prise en charge correcte de l'héritage multiple (et il ne fonctionne ensuite que si chaque classe l'utilise correctement). En général, AnyClass.w Whatever va rechercher quel que soit dans les ancêtres de AnyClass si AnyClass ne le fait pas. définissez-le / remplacez-le, et cela est vrai pour "la méthode du parent appelant une classe enfant". comme pour tout autre événement!

Python 3 utilise une syntaxe différente et plus simple pour appeler une méthode parent.

Si la classe Foo hérite de Bar , puis de Bar .__ init __ peut être appelé à partir de Foo via < code> super () .__ init __ () :

class Foo(Bar):

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

De nombreuses réponses ont expliqué comment appeler une méthode du parent qui a été remplacée par l'enfant.

Cependant

  

"Comment appelez-vous la méthode d'une classe parent à partir d'une classe enfant?"

pourrait aussi simplement signifier:

  

"Comment appelez-vous les méthodes héritées?"

Vous pouvez appeler des méthodes héritées d'une classe parent comme si elles étaient des méthodes de la classe enfant, tant qu'elles n'ont pas été écrasées.

par exemple. 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 paraître assez évident, mais j’ai le sentiment que, sans le signaler, il est possible que des personnes laissent ce fil avec l’impression que vous devez sauter à travers des cercles ridicules pour accéder aux méthodes héritées en python. D'autant plus que cette question accorde une grande importance aux recherches sur "comment accéder à la méthode d'une classe parente en Python", et que l'OP est écrit du point de vue de quelqu'un de novice en python.

j'ai trouvé: https://docs.python.org/3/tutorial/classes.html#inheritance pour vous aider à comprendre comment accéder aux méthodes héritées.

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

Il y a aussi un super () en Python. C'est un peu bizarre, à cause des classes de style ancien et nouveau 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 recommanderais 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 connaissez pas le nombre d'arguments que vous pourriez obtenir et souhaitez également les transmettre à l'enfant:

class Foo(bar)
    def baz(self, arg, *args, **kwargs):
        # ... Do your thing
        return super(Foo, self).baz(arg, *args, **kwargs)

(De: )

Il existe également un super () en python.

Exemple d'utilisation d'une méthode de super classe à 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 toutefois une différence: aucun argument ne lui est transmis par super.Ce code ci-dessus est exécutable dans la version 3.4 de Python.

En Python 2, je n’avais pas beaucoup de chance avec super (). J'ai utilisé la réponse de comment jimifiki sur ce fil SO faire référence à une méthode parente en python ? . Ensuite, j’y ai ajouté ma petite touche personnelle, ce qui, à mon avis, constitue une amélioration de la convivialité (surtout si vous avez des noms de classe longs).

Définissez la classe de base dans un module:

 # myA.py

class A():     
    def foo( self ):
        print "foo"

Importez ensuite la classe dans un autre module en tant que parent :

# myB.py

from myA import A as parent

class B( parent ):
    def foo( self ):
        parent.foo( self )   # calls 'A.foo()'

dans cet exemple cafec_param est une classe de base (classe parent) et abc est une classe enfant. abc appelle la méthode AWC dans la classe de base.

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())

Sortie

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()

Ceci est une méthode plus abstraite:

super(self.__class__,self).baz(arg)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top