Maison >développement back-end >Tutoriel Python >Explication sur la différence entre super() et __init__() dans les classes python

Explication sur la différence entre super() et __init__() dans les classes python

高洛峰
高洛峰original
2017-03-16 16:08:291443parcourir

Lorsque un seul hérite de , les fonctions implémentées par super() et init() sont similaires

class Base(object):
    def init(self):
        print 'Base create'
class childA(Base):
    def init(self):
        print 'creat A ',
        Base.init(self)
class childB(Base):
    def init(self):
        print 'creat B ',
        super(childB, self).init()
base = Base()
a = childA()
b = childB()

Résultat de sortie :

Base create
creat A  Base create
creat B  Base create

La différence est que lors de l'utilisation de l'héritage super(), il n'est pas nécessaire de référencer explicitement la classe de base.


super() ne peut être utilisé que dans les classes de nouveau style


Changez la classe de base en une classe à l'ancienne, c'est-à-dire qu'elle n'hérite d'aucune classe de base. Lorsque

class Base():
    def init(self):
        print 'Base create'

est exécuté, une erreur sera signalée lors de l'initialisation de b :

super(childB, self).init()
TypeError: must be type, not classobj


super n'est pas une classe parent. Au lieu de cela, la classe suivante dans la séquence d'héritage


impliquera la séquence d'héritage dans l'héritage multiple super(). équivaut à renvoyer la classe suivante dans la séquence d'héritage, pas la classe parent. Une fonction similaire à celle-ci :

def super(class_name, self):
    mro = self.class.mro()
    return mro[mro.index(class_name) + 1]
mro() est utilisée pour obtenir l'ordre d'héritage d'une classe. Par exemple :

class Base(object):
    def init(self):
        print 'Base create'
class childA(Base):
    def init(self):
        print 'enter A '
        # Base.init(self)
        super(childA, self).init()
        print 'leave A'
class childB(Base):
    def init(self):
        print 'enter B '
        # Base.init(self)
        super(childB, self).init()
        print 'leave B'
class childC(childA, childB):
    pass
c = childC()
print c.class.mro
Le résultat de sortie est le suivant :

enter A 
enter B 
Base create
leave B
leave A
(<class &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)
supder n'est pas lié à la classe parent, donc l'ordre d'exécution est A —> —>Base


Le processus d'exécution est équivalent à : lors de l'initialisation de childC(), super(childA, self).init() dans la

méthode constructeur sera appelé en premier, super(childA, self) renvoie une classe childB après childA dans l'ordre d'héritage de la classe actuelle ; puis exécutez childB().init(), et la séquence continue.


En héritage multiple, si vous remplacez super(childA, self).init() dans childA() par Base._init_(self), pendant l'exécution, après avoir hérité de childA , il passera directement à la classe Base, tout en sautant childB :

Comme le montre la méthode super(), le premier paramètre de super() peut être n'importe quoi dans la chaîne d'héritage. Le nom d'une classe,
enter A 
Base create
leave A
(<class &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)


, si elle est elle-même, elle héritera à son tour de la classe suivante


si c'est une chaîne d'héritage Les classes avant elle seront

récursives

indéfiniment


S'il s'agit d'une classe après la chaîne d'héritage, le résumé de la chaîne d'héritage elle-même ; et la classe entrante sera ignorée. Classes entre


Par exemple, si super dans childA() est remplacé par : super(childC, self).init(), le le programme se répétera à l'infini. Par exemple :

  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
RuntimeError: maximum recursion depth exceeded while calling a Python object


super() peut éviter les appels répétés à


Si childA est basé sur Base , childB hérite de childA Avec Base, si childB doit appeler la méthode init() de Base, cela entraînera l'exécution de init() deux fois :

La méthode init() de Base est exécutée deux fois
class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        Base.init(self)
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        childA.init(self)
        Base.init(self)
b = childB()

enter A 
Base create
leave A
Base create


L'utilisation de super() peut éviter les appels répétés

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        super(childA, self).init()
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        super(childB, self).init()
b = childB()
print b.class.mro()
enter A 
Base create
leave A
[<class &#39;main.childB&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn