Herencia múltiple de Python: Escoger a qué super () llamar

En Python, ¿cómo selecciono el método de Parent para llamar? Digamos que quiero llamar al método __init__ del __init__ padre. Parece que tengo que especificar ASDF1 en el super () ..? Y si quiero llamar a __init__ de __init__ , entonces debo especificar ASDF2 .

 >>> class ASDF(ASDF1, ASDF2, ASDF3): def __init__(self): super(ASDF1, self).__init__() >>> ASDF() ASDF2's __init__ happened >>> class ASDF(ASDF1, ASDF2, ASDF3): def __init__(self): super(ASDF2, self).__init__() >>> ASDF() ASDF3's __init__ happened 

Me parece loco. ¿Qué estoy haciendo mal?

Eso no es para lo que es super() . Super básicamente escoge a uno (o todos) de sus padres en un orden específico. Si solo desea llamar al método de un solo padre, haga esto

 class ASDF(ASDF1, ASDF2, ASDF3): def __init__(self): ASDF2.__init__(self) 

super llama al siguiente método en el orden de resolución de métodos. En un árbol de herencia lineal, ese será el método de la clase primaria inmediata.

Aquí, tiene tres padres, y el siguiente método ASDF1 desde la perspectiva de ASDF2 es el de ASDF2 . En general, lo más seguro es pasar la primera clase de la lista de herencia a super menos que sepa por qué quiere hacer otra cosa.

El objective de todo esto es liberarlo de tener que elegir explícitamente a qué métodos __init__ llamar. La pregunta aquí es por qué no desea llamar a todos los métodos de superclase __init__ .

Existe una literatura bastante importante sobre el uso de super en python, y le recomiendo que busque en Google el tema y lea los resultados.

Estás pasando ASDF1 (una de tus clases primarias) como el primer argumento a super (). No hagas eso En su lugar, debe pasar ASDF como primer argumento a super ().

Documentación de Python 2.7 para super ()

Para citar los documentos de Python 2.7, una llamada típica de superclase se ve así:

 class C(B): def method(self, arg): super(C, self).method(arg) 

Observe que el primer argumento para super aquí es C, que es la clase actual. No pase B (la clase padre) a super ().

Cuando se determina la orden de resolución de métodos (MRO), la persona omite la clase que se pasa como primer argumento y comienza a mirar a los padres y hermanos de esa clase. Entonces, cuando pasaste ASDF1 como el primer argumento de super (), saltó sobre ASDF1 y comenzó su búsqueda con ASDF2. Por eso se llamó __init__ de __init__ .


En Python 3, ya no tienes que pasar la clase actual.

 class C(B): def method(self, arg): super().method(arg) # This does the same thing as: # super(C, self).method(arg) # (Python 3 only)