Originalmente eu queria fazer essa pergunta , mas descobri que já havia pensado nela antes ...
Procurando no Google, encontrei este exemplo de extensão do configparser . O seguinte funciona com 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()
Mas não com 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
Então eu li um pouco sobre estilos Python New Class vs. Old Class (por exemplo, aqui . E agora estou pensando, posso fazer:
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"""
Mas, eu não deveria chamar init? Isso em Python 2 é o equivalente:
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)
python
inheritance
configparser
Oz123
fonte
fonte
__init__()
na subclasse se tudo o que ele faz é chamar a superclasse '__init__()
(no Python 2 ou 3) - em vez disso, apenas deixe os super serem herdados.Respostas:
super()
(sem argumentos) foi introduzido no Python 3 (junto com__class__
):de modo que seria o equivalente em Python 2 para classes de novo estilo:
para aulas de estilo antigo, você sempre pode usar:
fonte
super(__class__)
dáNameError: global name '__class__' is not defined
e tambémsuper(self.__class__)
está errado. Você deve fornecer uma instância como um segundo argumento, o que sugere que você precisa fazersuper(self.__class__, self)
, mas isso está errado . SeClass2
herdaClass1
eClass1
chamadassuper(self.__class__, self).__init__()
,Class1
's__init__
, em seguida, chamar-se ao instanciar uma instânciaClass2
.TypeError: super() takes at least 1 argument (0 given)
quando tento chamarsuper(self.__class__)
Python 2. (O que não faz muito sentido, mas demonstra quanta informação está faltando nesta resposta.)__init__()
sem discussão sobre o objeto de super não ligado (que você começa chamandosuper(self.__class__)
com apenas um argumento), você precisa de um objeto super-bound, então ele deve funcionar:super(CurrentClass, self).__init__()
. Não useself.__class__
porque isso sempre fará referência à mesma classe ao chamar um pai e, portanto, criar um loop infinito se esse pai também fizer o mesmo.__class__
(membro) também existe no Python2 .__class__
membro, mas sim do fechamento lexical implicitamente criado__class__
que sempre se refere à classe que está sendo definida, que não existe em python2.Em um único caso de herança (quando você cria uma subclasse de apenas uma classe), sua nova classe herda os métodos da classe base. Isso inclui
__init__
. Então, se você não definir em sua classe, você obterá o da base.As coisas começam a ficar complicadas se você introduzir herança múltipla (subclassificação de mais de uma classe por vez). Isso ocorre porque se houver mais de uma classe base
__init__
, sua classe herdará apenas a primeira.Nesses casos, você realmente deve usar
super
se puder, vou explicar por quê. Mas nem sempre você pode. O problema é que todas as suas classes básicas também devem usá-lo (e suas classes básicas também - a árvore inteira).Se for esse o caso, então isso também funcionará corretamente (no Python 3, mas você pode retrabalhá-lo no Python 2 - ele também funcionou
super
):Observe como ambas as classes base usam
super
, embora não tenham suas próprias classes base.O que
super
faz é: ele chama o método da próxima classe em MRO (ordem de resolução do método). A MRO paraC
é:(C, A, B, object)
. Você pode imprimirC.__mro__
para ver.Portanto,
C
herda__init__
deA
esuper
emA.__init__
chamadasB.__init__
(B
segueA
em MRO).Então, ao não fazer nada
C
, você acaba chamando os dois, que é o que você quer.Agora, se você não estivesse usando
super
, acabaria herdandoA.__init__
(como antes), mas desta vez não há nada que chameB.__init__
por você.Para corrigir isso, você deve definir
C.__init__
:O problema com isso é que em árvores MI mais complicadas, os
__init__
métodos de algumas classes podem acabar sendo chamados mais de uma vez, enquanto super / MRO garantem que sejam chamados apenas uma vez.fonte
Notice how both base classes use super even though they don't have their own base classes.
Eles têm. Em py3k, todos os objetos de subclasses de classe.Em suma, eles são equivalentes. Vamos ver o histórico:
(1) a princípio, a função se parece com isso.
(2) para tornar o código mais abstrato (e mais portátil). Um método comum para obter a Superclasse é inventado como:
E a função init pode ser:
No entanto, exigir uma passagem explícita da classe e da instância quebra um pouco a regra DRY (Don't Repeat Yourself).
(3) em V3. É mais inteligente,
é suficiente na maioria dos casos. Você pode consultar http://www.python.org/dev/peps/pep-3135/
fonte
Apenas para ter um exemplo simples e completo para Python 3, que a maioria das pessoas parece estar usando agora.
dá
fonte
Outra implementação do python3 que envolve o uso de classes Abstract com super (). Você deve se lembrar disso
tem o mesmo efeito que
Lembre-se de que há um 'self' oculto em super (). Portanto, o mesmo objeto passa para o método init da superclasse e os atributos são adicionados ao objeto que o chamou. Portanto,
super()
é traduzido paraPerson
e, se você incluir o self oculto, obterá o frag de código acima.fonte