Como inicializar a (super) classe base?
class SuperClass(object):
def __init__(self, x):
self.x = x
class SubClass(SuperClass):
def __init__(self, y):
self.y = y
Use um super
objeto para garantir que você obtenha o próximo método (como método vinculado) na ordem de resolução do método. No Python 2, você precisa passar o nome da classe e self
super para pesquisar o __init__
método bound :
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
No Python 3, há um pouco de mágica que torna os argumentos super
desnecessários - e, como benefício colateral, funciona um pouco mais rápido:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
A codificação codificada do pai como esta abaixo impede que você use herança múltipla cooperativa:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
Observe que __init__
só pode retornarNone
- ele pretende modificar o objeto no local.
Alguma coisa __new__
Há outra maneira de inicializar instâncias - e é a única maneira de subclasses de tipos imutáveis no Python. Por isso é necessário se você quiser subclasse str
ou tuple
ou outro objeto imutável.
Você pode pensar que é um método de classe porque obtém um argumento implícito de classe. Mas na verdade é um método estático . Então, você precisa chamar __new__
com cls
explicitamente.
Normalmente retornamos a instância de __new__
, portanto, se você o fizer, também precisará chamar a __new__
via super
da sua base também na sua classe base. Portanto, se você usar os dois métodos:
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')
O Python 3 evita um pouco da estranheza das super chamadas causadas por __new__
ser um método estático, mas você ainda precisa passar cls
para o __new__
método não vinculado :
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')