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 superoggetto 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 selfa 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 superinutili 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 stro tupleo 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 clsesplicito.
Di solito restituiamo l'istanza da __new__, quindi se lo fai, devi anche chiamare anche __new__via superla 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 clsal __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')