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

高洛峰
Libérer: 2017-03-16 16:08:29
original
1455 Les gens l'ont consulté

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()
Copier après la connexion

Résultat de sortie :

Base create
creat A  Base create
creat B  Base create
Copier après la connexion

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'
Copier après la connexion

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

super(childB, self).init()
TypeError: must be type, not classobj
Copier après la connexion

<🎜. >

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]
Copier après la connexion
mro() est utilisée pour obtenir l'ordre d'héritage d'une classe. Par exemple :

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)
        super(childA, self).init()
        print &#39;leave A&#39;
class childB(Base):
    def init(self):
        print &#39;enter B &#39;
        # Base.init(self)
        super(childB, self).init()
        print &#39;leave B&#39;
class childC(childA, childB):
    pass
c = childC()
print c.class.mro
Copier après la connexion
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;>)
Copier après la connexion
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< de childA 🎜> 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;>)
Copier après la connexion


, 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
Copier après la connexion


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()
Copier après la connexion

enter A 
Base create
leave A
Base create
Copier après la connexion


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;>]
Copier après la connexion

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!

Étiquettes associées:
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal