En Python, considérez que j'ai le code suivant:
>>> class SuperClass(object):
def __init__(self, x):
self.x = x
>>> class SubClass(SuperClass):
def __init__(self, y):
self.y = y
# how do I initialize the SuperClass __init__ here?
Comment initialiser le SuperClass __init__
dans la sous-classe? Je suis le Python et il ne couvre pas cela. Lorsque j'ai effectué une recherche sur Google, j'ai trouvé plus d'une façon de le faire. Quelle est la manière habituelle de gérer cela?
Python (jusqu'à la version 3) supporte les classes "old-style" et new-style. Les classes de style nouveau sont dérivées de object
et sont ce que vous utilisez. Elles invoquent leur classe de base par le biais de super()
, par exemple.
class X(object):
def __init__(self, x):
pass
def doit(self, bar):
pass
class Y(X):
def __init__(self):
super(Y, self).__init__(123)
def doit(self, foo):
return super(Y, self).doit(foo)
Parce que python connaît les classes de style ancien et nouveau, il existe différentes façons d'invoquer une méthode de base, c'est pourquoi vous avez trouvé plusieurs façons de le faire.
Par souci d'exhaustivité, les classes de style ancien appellent des méthodes de base explicitement à l'aide de la classe de base, c'est-à-dire.
def doit(self, foo):
return X.doit(self, foo)
Mais comme vous ne devriez plus utiliser d'ancien style, cela ne m'intéresserait pas trop.
Python 3 ne connaît que les classes de style nouveau (peu importe si vous dérivez de object
ou pas).
Tous les deux
SuperClass.__init__(self, x)
ou
super(SubClass,self).__init__( x )
fonctionnera (je préfère le deuxième, car il adhère davantage au principe DRY)).
Voir ici: http://docs.python.org/reference/datamodel.html#basic-customization
À partir de python 3.5.2, vous pouvez utiliser:
class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)
Comment initialiser la (super) classe de base?
class SuperClass(object): def __init__(self, x): self.x = x class SubClass(SuperClass): def __init__(self, y): self.y = y
Utilisez un objet super
pour vous assurer d’obtenir la méthode suivante (en tant que méthode liée) dans l’ordre de résolution des méthodes. Dans Python 2, vous devez transmettre le nom de la classe et self
à super pour rechercher la méthode __init__
Liée:
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
Dans Python 3, il y a une petite magie qui rend les arguments de super
inutiles - et qui présente l'avantage d'être un peu plus rapide:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
Le codage en dur du parent comme ci-dessous vous empêche d'utiliser un héritage multiple coopératif:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
Notez que __init__
Peut uniquement renvoyer None
- il est destiné à modifier l'objet sur place.
__new__
Il existe un autre moyen d'initialiser les instances - et c'est le seul moyen pour les sous-classes de types immuables en Python. C'est donc nécessaire si vous voulez sous-classer str
ou Tuple
ou un autre objet immuable.
Vous pourriez penser que c'est une méthode de classe parce qu'elle obtient un argument de classe implicite. Mais c’est en fait, une méthode statique . Vous devez donc appeler explicitement __new__
Avec cls
.
Nous renvoyons habituellement l'instance de __new__
, Si vous le faites, vous devez également appeler le __new__
De votre base via super
également dans votre classe de base. Donc, si vous utilisez les deux méthodes:
class SuperClass(object):
def __new__(cls, x):
return super(SuperClass, cls).__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super(SubClass, cls).__new__(cls)
def __init__(self, y):
self.y = y
super(SubClass, self).__init__('x')
Python 3 évite un peu l'étrangeté des super-appels causés par le fait que __new__
Est une méthode statique, mais vous devez toujours passer cls
à la méthode non liée __new__
:
class SuperClass(object):
def __new__(cls, x):
return super().__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super().__new__(cls)
def __init__(self, y):
self.y = y
super().__init__('x')