Al crear una jerarquía de objetos simple en Python, me gustaría poder invocar métodos de la clase primaria desde una clase derivada. En Perl y Java, hay una palabra clave para this ( super
). En Perl, podría hacer esto:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
En Python, parece que tengo que nombrar la clase padre explícitamente desde el niño. En el ejemplo anterior, tendría que hacer algo como Foo::frotz()
.
Esto no parece correcto ya que este comportamiento dificulta la creación de jerarquías profundas. Si los niños necesitan saber qué clase definió un método heredado, entonces se crea todo tipo de dolor de información.
¿Es esta una limitación real en Python, un vacío en mi comprensión o ambos?
python
inheritance
class
object
jjohn
fuente
fuente
Respuestas:
Sí, pero solo con clases de estilo nuevo . Usa la
super()
función:Para python <3, use:
fuente
super(Foo, self)
es para Python 2.x ¿correcto? En Python 3.x, ¿super()
se prefiere el correcto?Python también tiene super :
super(type[, object-or-type])
Ejemplo:
fuente
estará bien, ya sea que la clase primaria inmediata se haya definido
frotz
o heredado.super
solo es necesario para el soporte adecuado de la herencia múltiple (y luego solo funciona si cada clase lo usa correctamente). En general,AnyClass.whatever
buscaráwhatever
enAnyClass
los antepasados siAnyClass
no lo define / anula, ¡y esto es válido para el "método de los padres que llaman a la clase secundaria" como para cualquier otra ocurrencia!fuente
parent
, está dentro del alcance de toda la clase, ¿no es así?Python 3 tiene una sintaxis diferente y más simple para llamar al método padre.
Si la
Foo
clase hereda deBar
, entoncesBar.__init__
se puede invocar desde aFoo
través desuper().__init__()
:fuente
Muchas respuestas han explicado cómo llamar a un método del padre que se ha anulado en el hijo.
sin embargo
También podría significar simplemente:
Puede llamar a los métodos heredados de una clase principal como si fueran métodos de la clase secundaria, siempre que no se hayan sobrescrito.
Por ejemplo, en Python 3:
Sí, esto puede ser bastante obvio, pero creo que sin señalar esto, las personas pueden dejar este hilo con la impresión de que tienes que saltar a través de aros ridículos solo para acceder a métodos heredados en Python. Especialmente porque esta pregunta tiene una alta calificación en las búsquedas de "cómo acceder al método de una clase primaria en Python", y el OP se escribe desde la perspectiva de alguien nuevo en python.
Encontré que: https://docs.python.org/3/tutorial/classes.html#inheritance es útil para comprender cómo accede a los métodos heredados.
fuente
self.string
no hará nada. En la clase C, sin embargo, todavía podría llamarB().bar(string)
Aquí hay un ejemplo del uso de super () :
fuente
También hay un super () en Python. Es un poco raro, debido a las clases de estilo antiguo y nuevo de Python, pero se usa con bastante frecuencia, por ejemplo, en constructores:
fuente
Yo recomendaría usar
CLASS.__bases__
algo como estofuente
Si no sabe cuántos argumentos puede obtener y desea pasarlos también al niño:
(De: Python: ¿la forma más limpia de anular __init__ donde se debe usar un kwarg opcional después de la llamada super ()? )
fuente
También hay un super () en python.
Ejemplo de cómo se llama a un método de superclase desde un método de subclase
Este ejemplo es similar al explicado anteriormente. Sin embargo, hay una diferencia de que super no tiene ningún argumento pasado. Este código anterior es ejecutable en la versión Python 3.4.
fuente
En este ejemplo
cafec_param
es una clase base (clase primaria) yabc
es una clase secundaria.abc
llama alAWC
método en la clase base.Salida
fuente
En Python 2, no tuve mucha suerte con super (). Utilicé la respuesta de jimifiki en este hilo SO, ¿cómo referirme a un método padre en python? . Luego, le agregué mi propio pequeño giro, lo que creo que es una mejora en la usabilidad (especialmente si tiene nombres de clase largos).
Defina la clase base en un módulo:
Luego importe la clase a otros módulos
as parent
:fuente
class A(object):
lugar declass A():
Entonces super () funcionaráfuente
fuente
Este es un método más abstracto:
fuente
super(self.__class__, self).baz(arg)
.