Come si inizializza la (super) classe di base?
class SuperClass(object):
def __init__(self, x):
self.x = x
class SubClass(SuperClass):
def __init__(self, y):
self.y = y
Usa un super
oggetto per assicurarti di ottenere il metodo successivo (come metodo associato) nell'ordine di risoluzione del metodo. In Python 2, devi passare il nome della classe e self
a super per cercare il __init__
metodo associato :
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
In Python 3, c'è un po 'di magia che rende gli argomenti super
inutili e, come vantaggio collaterale, funziona un po' più velocemente:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
L'hardcoding del genitore come questo di seguito ti impedisce di utilizzare l'ereditarietà multipla cooperativa:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
Nota che __init__
può solo restituireNone
: è destinato a modificare l'oggetto sul posto.
Qualcosa __new__
C'è un altro modo per inizializzare le istanze, ed è l'unico modo per le sottoclassi di tipi immutabili in Python. Quindi è necessario se si vuole sottoclasse str
o tuple
o di un altro oggetto immutabile.
Potresti pensare che sia un metodo di classe perché ottiene un argomento di classe implicito. Ma in realtà è un metodo statico . Quindi è necessario chiamare __new__
con cls
esplicito.
Di solito restituiamo l'istanza da __new__
, quindi se lo fai, devi anche chiamare anche __new__
via super
la tua base nella tua classe base. Quindi, se usi entrambi i metodi:
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 elude un po 'la stranezza delle super chiamate causate __new__
dall'essere un metodo statico, ma è comunque necessario passare cls
al __new__
metodo non vincolato :
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')