2009-01-21 12 views
12

Przy użyciu Pythona super() zrobić metoda łańcuchowym, trzeba wyraźnie określić swoją klasę, na przykład:Dlaczego muszę określić własną klasę podczas używania super() i czy istnieje sposób na obejście tego?

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

muszę podać nazwę mojej klasie MyDecorator jako argument do super(). To nie jest SUCHA. Kiedy zmieniam nazwę mojej klasy, będę musiał zmienić jej nazwę dwukrotnie. Dlaczego jest to realizowane w ten sposób? I czy istnieje sposób, aby wymazać z konieczności napisania nazwy klasy dwukrotnie (lub więcej)?

Odpowiedz

6

BDFL wyraża zgodę. Zobacz Pep 367 - New Super dla wersji 2.6 i PEP 3135 - New Super dla wersji 3.0.

+0

Link do aktualnej wersji PEP: http://www.python.org/dev/peps/pep-3135/ – sth

+0

'super()' bez argumentów nie * nie * działa na Pythonie 2.6.1 – jfs

+0

Wydaje się, że PEP 367 został "zastąpiony". Nie widzę dowodów na to, że dodano go do 2.7. Myślę, że jest to tylko funkcja 3.x. – Vultaire

11

Twoje życzenie się spełniło:

Wystarczy użyć pythona 3.0. W nim wystarczy użyć super() i ma on wartość super(ThisClass, self).

Dokumentacja here. przykładowy kod z dokumentacji:

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

można również uniknąć pisania konkretną nazwę klasy w starszych wersjach Pythona za pomocą

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

Nie, to nie zadziała, ponieważ __class__ da ci najbardziej specyficzną podklasę instancji, niekoniecznie tę w kontekście klasy, którą piszemy. – airportyh

+2

Uważam, że autorowi nie przysługuje prawo do głosowania na tę odpowiedź. Ta odpowiedź stanowi naiwne, ale często błędne przekonanie. To zasługuje na stwierdzenie tutaj, wraz z wyjaśnieniem toby'ego, dlaczego to nie działa. Warto w metodach raportowania, które NIE działają również. – gotgenes

3

Ta odpowiedź jest źle, spróbuj:

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 

W Pythonie 2 jest sposób użycia dekoratora:

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 
Powiązane problemy