2009-12-24 10 views
5

In Python 2.x akzeptiert Super folgende FälleWarum Python Super nicht nur Instanz akzeptieren?

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: 

soweit ich sehe, super ist eine Klasse, die Art Verpackung und (schließlich) die Instanz, die übergeordnete Klasse einer Klasse zu lösen.

bin ich ziemlich verwirrt durch ein paar Dinge:

  • warum auch gibt es keine super(instance), mit typischer Verwendung z.B. super(self).__init__(). Technisch gesehen können Sie den Typ eines Objekts vom Objekt selbst erhalten, daher ist die aktuelle Strategie super(ClassType, self).__init__() irgendwie redundant. Ich vermute Kompatibilitätsprobleme mit alten Klassen oder Mehrfachvererbung, aber ich würde gerne Ihren Standpunkt hören.
  • warum akzeptiert Python 3 (siehe Understanding Python super() with __init__() methods) super().__init__()? Ich sehe darin eine Art Magie, die das Explizite verletzt, ist besser als das implizite Zen. Ich hätte passender gesehen self.super().__init__().

Antwort

6

super(ClassType, self).__init__() ist nicht überflüssig in einer kooperativen Mehrfachvererbung scheme - ClassType ist nicht unbedingt die Art von self, aber die Klasse, von dem Sie den kooperativen Aufruf __init__ zu tun. Superklasse nennen init aus C's Perspektive

In der Klassenhierarchie C inherits B inherits A, in C.__init__ Sie wollen, und Sie rufen B.__init__; dann in B.__init__ müssen Sie die Klassenart B an Super übergeben - da Sie aufrufende Superklassen von B auflösen wollen (oder besser, die nächste in der Mro nach B der Klasse 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__() 

wenn Sie jetzt c = C() instanziiert, sehen Sie, dass der Klassentyp nicht redundant ist - super(self).__init__() innerhalb B.__init__ würde nicht wirklich funktionieren! Was Sie tun ist, dass Sie manuell angeben, in welcher Klasse die superaufrufende Methode ist (eine solche wird in Python 3 durch eine versteckte Variable gelöst, die auf die Klasse der Methode verweist).

Zwei Links mit Beispielen von Super- und Mehrfachvererbung:

+0

Ich denke du meinst Klasse B (A): und Klasse C (B): –

+0

Allerdings hast du recht. Es wäre niemals in der Lage, A .__ init __() von B aufzurufen, weil in Methode B .__ init __() self vom Typ C wäre, dessen direkter Super B ist, nicht A. Also würde B .__ init __() erneut aufgerufen werden. –

+0

ah Sie haben Recht mit dem Tippfehler, danke! Und das wird in mehreren Vererbungsschemas noch komplizierter, ich denke, ich kann einen Link dazu finden. – u0b34a0f6ae

3

Ich kann keine spezifische Antwort geben, aber haben Sie die PEPs um das Super-Schlüsselwort gelesen? Ich habe eine schnelle Google-Suche und es kam mit PEP 367 und PEP 3135.

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

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

Im Gegensatz zu anderen Sprache, die ich kenne, die meiste Zeit Sie die Antworten auf Python finden Macken in den PEPs zusammen mit klaren rationalen und Positionsaussagen.

Update:

durch 3135, ähnliche E-Mails in dem Python-Mailing gelesen und die Sprache verweisen sie Art Sinn machen, warum es die Art und Weise ist es für Python 2 vs Python ist 3.

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

Ich denke, Super wurde explizit/redundant implementiert, nur um auf der sicheren Seite zu sein und die Logik so einfach wie möglich zu halten (kein Zucker oder tiefe Logik, um die Eltern zu finden). Da super eine eingebaute Funktion ist, muss es die korrekte Rückkehr von dem, was bereitgestellt wird, ableiten, ohne die Python-Objekte zu komplizieren.

PEP 3135 ändert alles, weil es präsentiert und gewann ein Argument für eine DRY'er Ansatz zu Super.

+0

Ich bin damit einverstanden, aber ich versuche, eine Antwort auf die Frage _while_ zur gleichen Zeit zu bekommen Erhöhung Stapelüberlaufinformationen. –

+0

@Stefano Unmittelbar nachdem ich meinen ursprünglichen Beitrag gemacht hatte, fing ich an, dasselbe zu denken. – David

Verwandte Themen