2009-12-24 16 views
5

En Python 2.x, super acepta los siguientes casos¿Por qué python super no acepta solo la instancia?

class super(object) 
| super(type) -> unbound super object 
| super(type, obj) -> bound super object; requires isinstance(obj, type) 
| super(type, type2) -> bound super object; requires issubclass(type2, type) 
| Typical use to call a cooperative superclass method: 

por lo que yo veo, super es una clase, envolviendo el tipo y (eventualmente) la instancia para resolver la superclase de una clase.

estoy bastante desconcertado por un par de cosas:

  • por eso tampoco hay super(instance), con el uso típico, por ejemplo, super(self).__init__(). Técnicamente, puede obtener el tipo de un objeto del propio objeto, por lo que la estrategia actual super(ClassType, self).__init__() es algo redundante. Supongo que hay problemas de compatibilidad con las clases antiguas o la herencia múltiple, pero me gustaría escuchar su punto.
  • por qué, por otro lado, python 3 aceptará (consulte Understanding Python super() with __init__() methods) super().__init__()? Veo algo de magia en esto, violar lo explícito es mejor que el Zen implícito. Hubiera visto más apropiado self.super().__init__().

Respuesta

6

super(ClassType, self).__init__() es no redundante en un esquema de herencia múltiple cooperativa - ClassType no es necesariamente el tipo de self, pero la clase de la que desea hacer la llamada cooperativa para __init__.

En la jerarquía de clases C inherits B inherits A, en C.__init__ que desea llamar init superclase de C's perspectiva, y se llama a B.__init__; luego en B.__init__ debe pasar el tipo de clase B a super - ya que desea resolver las superclases llamantes de B (o más bien, la siguiente en el mro después de B de la clase C).

class A (object): 
    def __init__(self): 
    pass 

class B (A): 
    def __init__(self): 
    super(B, self).__init__() 

class C (B): 
    def __init__(self): 
    super(C, self).__init__() 

si ahora c = C() una instancia, se ve que el tipo de clase no es redundante - super(self).__init__() dentro B.__init__ no sería realmente funcionan! Lo que debes hacer es especificar manualmente en qué clase está el método que llama super (esto se resuelve en el super de Python 3 mediante una variable oculta que apunta a la clase del método).

dos enlaces con ejemplos de super y la herencia múltiple:

+0

Supongo que quería decir clase B (A): y clase C (B): –

+0

Sin embargo, tiene razón. Nunca sería capaz de llamar a A .__ init __() desde B, porque en el método B .__ init __() self sería de tipo C, cuyo super directo es B, no A. Entonces, B .__ init __() se llamaría de nuevo. –

+0

ah tienes razón sobre el error tipográfico, ¡gracias! Y esto se vuelve aún más complicado en los esquemas de herencia múltiple, creo que puedo encontrar un enlace sobre eso. – u0b34a0f6ae

3

No puedo proporcionar una respuesta específica, pero ¿ha leído el PEP alrededor de la palabra clave super? Hice una búsqueda rápida de Google y que venía con PEP 367 y PEP 3135.

http://www.python.org/dev/peps/pep-0367/

http://www.python.org/dev/peps/pep-3135/#numbering-note

A diferencia de cualquier otro idioma que conozco, la mayoría de las veces se pueden encontrar las respuestas a Python peculiaridades en los PEP junto con claras declaraciones racionales y de posición.

Actualización:

Después de haber leído a través de 3135, los correos electrónicos relacionados con el correo Python y el idioma de referencia es como que tiene sentido por qué es la forma en que es para Python 2 vs Python 3.

http://docs.python.org/library/functions.html?highlight=super#super

Creo que super se implementó para ser explícito/redundante sólo para estar en el lado seguro y mantener la lógica involucrada lo más simple posible (sin azúcar o lógica profunda para encontrar el padre). Como super es una función incorporada, debe inferir el retorno correcto de lo que se proporciona sin agregar más complicaciones a la estructura de los objetos de Python.

PEP 3135 lo cambia todo porque presentó y ganó un argumento para un acercamiento de DRY'er a super.

+0

Estoy de acuerdo, pero estoy tratando de obtener una respuesta a la _while_ pregunta al mismo tiempo aumentar información de stackoverflow. –

+0

@Stefano Inmediatamente después de hacer mi publicación original comencé a pensar lo mismo. – David

Cuestiones relacionadas