2009-01-21 14 views
12

Wenn super() Python mit der Methode Verkettung zu tun, müssen Sie explizit eine eigene Klasse angeben, zum Beispiel:Warum muss ich bei der Verwendung von super() meine eigene Klasse angeben, und gibt es eine Möglichkeit, diese zu umgehen?

class MyDecorator(Decorator): 
    def decorate(self): 
     super(MyDecorator, self).decorate() 

ich den Namen meiner Klasse MyDecorator als Argument an super() angeben müssen. Dies ist nicht trocken. Wenn ich meine Klasse umbenenne, muss ich sie zweimal umbenennen. Warum wird das so umgesetzt? Und gibt es eine Möglichkeit, den Namen der Klasse zweimal (oder mehr) zu schreiben?

Antwort

6

Der BDFL stimmt zu. Siehe Pep 367 - New Super für 2.6 und PEP 3135 - New Super für 3.0.

+0

Link zur aktuellen Version des PEP: http://www.python.org/dev/peps/pep-3135/ – sth

+0

'super()' ohne Argumente funktioniert * nicht * auf Python 2.6.1 – jfs

+0

PEP 367 scheint "überholt" worden zu sein. Ich sehe keinen Beweis dafür, dass dies zu 2.7 hinzugefügt wurde. Ich denke, es ist nur eine 3.x-Funktion. – Vultaire

11

Ihre Wünsche werden wahr:

Verwenden Sie einfach Python 3.0. In ihm verwenden Sie einfach super() und es tut super(ThisClass, self).

Dokumentation here. Codebeispiel aus der Dokumentation:

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

Sie auch eine konkrete Klasse zu schreiben Namen in älteren Versionen von Python unter Verwendung

def __init__(self): 
    super(self.__class__, self) 
    ... 
+4

Nein, das wird nicht funktionieren, weil __class__ Ihnen die spezifischste Unterklasse für die Instanz liefert, nicht unbedingt die im Kontext der Klasse, die wir schreiben. – airportyh

+2

Ich finde es unfair gegenüber dem Autor, diese Antwort zu stimmen. Diese Antwort ist ein naives, aber weit verbreitetes Missverständnis. Es verdient, hier zu sagen, zusammen mit Tobys Erklärung, warum dies nicht funktioniert. Es gibt Methoden, die auch NICHT funktionieren. – gotgenes

3

Diese Antwort falsch ist, versuchen Sie vermeiden:

def _super(cls): 
    setattr(cls, '_super', lambda self: super(cls, self)) 
    return cls 

class A(object): 
    def f(self): 
     print 'A.f' 

@_super 
class B(A): 
    def f(self): 
     self._super().f() 

@_super 
class C(B): 
    def f(self): 
     self._super().f() 

C().f() # maximum recursion error 

In Python 2 gibt es einen Weg mit Dekorator:

def _super(cls): 
    setattr(cls, '_super', lambda self: super(cls, self)) 
    return cls 

class A(object): 
    def f(self): 
     print 'A.f' 

@_super 
class B(A): 
    def f(self): 
     self._super().f() 

B().f() # >>> A.f