Au départ je voulais poser cette question , mais ensuite j'ai trouvé qu'on y avait déjà pensé avant ...
En cherchant sur Google, j'ai trouvé cet exemple d' extension de configparser . Ce qui suit fonctionne avec Python 3:
$ python3
Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51)
[GCC 4.6.3] on linux2
>>> from configparser import SafeConfigParser
>>> class AmritaConfigParser(SafeConfigParser):
... def __init_(self):
... super().__init__()
...
>>> cfg = AmritaConfigParser()
Mais pas avec Python 2:
>>> class AmritaConfigParser(SafeConfigParser):
... def __init__(self):
... super(SafeConfigParser).init()
...
>>> cfg = AmritaConfigParser()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: must be type, not classob
Ensuite, j'ai lu un peu sur les styles Python New Class vs Old Class (par exemple ici . Et maintenant je me demande, je peux faire:
class MyConfigParser(ConfigParser.ConfigParser):
def Write(self, fp):
"""override the module's original write funcition"""
....
def MyWrite(self, fp):
"""Define new function and inherit all others"""
Mais, ne devrais-je pas appeler init? Est-ce que c'est en Python 2 l'équivalent:
class AmritaConfigParser(ConfigParser.SafeConfigParser):
#def __init__(self):
# super().__init__() # Python3 syntax, or rather, new style class syntax ...
#
# is this the equivalent of the above ?
def __init__(self):
ConfigParser.SafeConfigParser.__init__(self)
__init__()
dans la sous-classe si tout ce qu'il fait est d'appeler la super classe '__init__()
(en Python 2 ou 3) - au lieu de cela, laissez simplement les super être hérités.Réponses:
super()
(sans arguments) a été introduit dans Python 3 (avec__class__
):ce serait donc l'équivalent Python 2 pour les classes de style nouveau:
pour les classes à l'ancienne, vous pouvez toujours utiliser:
la source
super(__class__)
donneNameError: global name '__class__' is not defined
etsuper(self.__class__)
est également erroné. Vous devez fournir une instance comme deuxième argument, ce qui suggère que vous devez le fairesuper(self.__class__, self)
, mais c'est faux . SiClass2
hérite deClass1
etClass1
appelssuper(self.__class__, self).__init__()
,Class1
est__init__
sera alors appeler lui - même lors de l' instanciation d' une instance deClass2
.TypeError: super() takes at least 1 argument (0 given)
en essayant d'appelersuper(self.__class__)
Python 2. (Ce qui n'a pas beaucoup de sens, mais cela montre combien d'informations manquent à cette réponse.)__init__()
sans argument l'objet super non liée (que vous obtenez en appelantsuper(self.__class__)
avec un seul argument), vous avez besoin d' un objet super lié alors il devrait fonctionner:super(CurrentClass, self).__init__()
. Ne l'utilisez pasself.__class__
car cela fera toujours référence à la même classe lors de l'appel d'un parent et donc créera une boucle infinie si ce parent fait également la même chose.__class__
(membre) existe également en Python2 .__class__
membre mais de la fermeture lexicale implicitement créée__class__
qui fait toujours référence à la classe en cours de définition, qui n'existe pas dans python2.Dans un cas d'héritage unique (lorsque vous sous-classez une seule classe), votre nouvelle classe hérite des méthodes de la classe de base. Cela comprend
__init__
. Donc, si vous ne le définissez pas dans votre classe, vous obtiendrez celui de la base.Les choses commencent à être compliquées si vous introduisez l'héritage multiple (sous-classant plus d'une classe à la fois). En effet, si plus d'une classe de base en a
__init__
, votre classe héritera de la première uniquement.Dans de tels cas, vous devriez vraiment utiliser
super
si vous le pouvez, je vais vous expliquer pourquoi. Mais pas toujours vous le pouvez. Le problème est que toutes vos classes de base doivent également l'utiliser (ainsi que leurs classes de base - tout l'arborescence).Si tel est le cas, cela fonctionnera également correctement (en Python 3 mais vous pouvez le retravailler en Python 2 - il a également
super
):Remarquez comment les deux classes de base utilisent
super
même si elles n'ont pas leurs propres classes de base.Qu'est
super
- ce que c'est: il appelle la méthode de la classe suivante dans MRO (ordre de résolution des méthodes). Le MRO pourC
est:(C, A, B, object)
. Vous pouvez imprimerC.__mro__
pour le voir.Donc,
C
hérite__init__
deA
etsuper
dans lesA.__init__
appelsB.__init__
(B
suitA
dans MRO).Donc, en ne faisant rien
C
, vous finissez par appeler les deux, ce que vous voulez.Maintenant, si vous n'utilisiez pas
super
, vous finiriez par hériterA.__init__
(comme avant) mais cette fois, il n'y a rien qui puisse vous appelerB.__init__
.Pour résoudre ce problème, vous devez définir
C.__init__
:Le problème avec cela est que dans les arbres MI plus compliqués, les
__init__
méthodes de certaines classes peuvent finir par être appelées plus d'une fois alors que super / MRO garantit qu'elles ne sont appelées qu'une seule fois.la source
Notice how both base classes use super even though they don't have their own base classes.
Ils ont. Dans py3k, chaque classe sous-classe un objet.Bref, ils sont équivalents. Ayons une vue historique:
(1) au début, la fonction ressemble à ceci.
(2) pour rendre le code plus abstrait (et plus portable). Une méthode courante pour obtenir Super-Class est inventée comme:
Et la fonction init peut être:
Cependant, exiger un passage explicite de la classe et de l'instance enfreint un peu la règle DRY (Don't Repeat Yourself).
(3) en V3. C'est plus intelligent,
est suffisant dans la plupart des cas. Vous pouvez vous référer à http://www.python.org/dev/peps/pep-3135/
la source
Juste pour avoir un exemple simple et complet pour Python 3, que la plupart des gens semblent utiliser maintenant.
donne
la source
Une autre implémentation de python3 qui implique l'utilisation de classes abstraites avec super (). Tu devrais te rappeler que
a le même effet que
Souvenez-vous qu'il y a un 'self' caché dans super (), donc le même objet passe à la méthode init de la superclasse et les attributs sont ajoutés à l'objet qui l'a appelé. Par conséquent, il
super()
est traduit enPerson
et si vous incluez le soi caché, vous obtenez le fragment de code ci-dessus.la source