Originalmente quería hacer esta pregunta , pero luego descubrí que ya se había pensado antes ...
Buscando en Google encontré este ejemplo de extensión de configparser . Lo siguiente funciona con 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()
Pero no con 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
Luego leí un poco sobre los estilos Python New Class vs. Old Class (por ejemplo, aquí . Y ahora me pregunto, puedo hacer:
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"""
Pero, ¿no debería llamar a init? ¿Es esto en Python 2 el 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
fuente
fuente
__init__()
en la subclase si todo lo que hace es llamar a la superclase '__init__()
(en Python 2 o 3); en su lugar, deje que las superclase se hereden.Respuestas:
super()
(sin argumentos) se introdujo en Python 3 (junto con__class__
):por lo que sería el equivalente de Python 2 para clases de nuevo estilo:
para clases de estilo antiguo siempre puede usar:
fuente
super(__class__)
daNameError: global name '__class__' is not defined
y tambiénsuper(self.__class__)
es erróneo. Usted debe proporcionar una instancia como segundo argumento, lo que sugeriría que tiene que hacersuper(self.__class__, self)
, pero eso es incorrecto . SiClass2
hereda deClass1
yClass1
llamasuper(self.__class__, self).__init__()
,Class1
's__init__
se llamará a sí mismo al crear una instancia deClass2
.TypeError: super() takes at least 1 argument (0 given)
cuando intento llamarsuper(self.__class__)
en Python 2. (Lo cual no tiene mucho sentido, pero demuestra cuánta información falta en esta respuesta).__init__()
sin discusión en el súper objeto independiente (que se obtiene llamandosuper(self.__class__)
sólo con un argumento), se necesita un súper objeto dependiente entonces debería funcionar:super(CurrentClass, self).__init__()
. No lo useself.__class__
porque siempre se referirá a la misma clase al llamar a un padre y, por lo tanto, creará un bucle infinito si ese padre también hace lo mismo.__class__
(miembro) también existe en Python2 .__class__
miembro, sino del cierre léxico creado implícitamente__class__
que siempre se refiere a la clase que se está definiendo actualmente, que no existe en python2.En un solo caso de herencia (cuando subclasifica una sola clase), su nueva clase hereda métodos de la clase base. Esto incluye
__init__
. Entonces, si no lo define en su clase, obtendrá el de la base.Las cosas comienzan a complicarse si introduce herencia múltiple (subclasificando más de una clase a la vez). Esto se debe a que si tiene más de una clase base
__init__
, su clase heredará solo la primera.En tales casos, realmente debería usar
super
si puede, le explicaré por qué. Pero no siempre se puede. El problema es que todas sus clases base también deben usarlo (y sus clases base también - todo el árbol).Si ese es el caso, entonces esto también funcionará correctamente (en Python 3, pero podría volver a trabajarlo en Python 2, también lo ha hecho
super
):Observe cómo se usan ambas clases base
super
aunque no tengan sus propias clases base.Lo que
super
hace es: llama al método de la siguiente clase en MRO (orden de resolución del método). El MROC
es:(C, A, B, object)
. Puedes imprimirC.__mro__
para verlo.Entonces,
C
hereda__init__
deA
ysuper
enA.__init__
llamadasB.__init__
(B
sigueA
en MRO).Entonces, al no hacer nada en
C
, terminas llamando a ambos, que es lo que quieres.Ahora bien, si no estuvieras usando
super
, terminarías heredandoA.__init__
(como antes) pero esta vez no hay nada que te llameB.__init__
.Para arreglar eso tienes que definir
C.__init__
:El problema con eso es que en árboles MI más complicados, los
__init__
métodos de algunas clases pueden terminar llamándose más de una vez, mientras que super / MRO garantizan que se llamen solo una vez.fuente
Notice how both base classes use super even though they don't have their own base classes.
Ellos tienen. En py3k cada objeto de subclases de clase.En resumen, son equivalentes. Tengamos una vista del historial:
(1) al principio, la función se ve así.
(2) para hacer el código más abstracto (y más portátil). Un método común para obtener Super-Class se inventa como:
Y la función init puede ser:
Sin embargo, al requerir una aprobación explícita tanto de la clase como de la instancia, se rompe un poco la regla DRY (Don't Repeat Yourself).
(3) en V3. Es más inteligente
es suficiente en la mayoría de los casos. Puede consultar http://www.python.org/dev/peps/pep-3135/
fuente
Solo para tener un ejemplo simple y completo para Python 3, que la mayoría de la gente parece estar usando ahora.
da
fuente
Otra implementación de python3 que implica el uso de clases abstractas con super (). Deberías recordar eso
tiene el mismo efecto que
Recuerde que hay un 'self' oculto en super (), por lo que el mismo objeto pasa al método init de la superclase y los atributos se agregan al objeto que lo llamó. Por lo tanto,
super()
se traduce ayPerson
luego, si incluye el yo oculto, obtiene el fragmento de código anterior.fuente