Dekorator wird nur 1x ausgeführt
Verfasst: Samstag 5. Januar 2008, 16:21
Hallo allerseits
Ich habe mal zwei Beispiele mit Dekoratoren geschrieben, das erste (einfachere) funktioniert perfekt:
quadrieren.py
Die Ausgabe dazu lautet:
Ich dekoriere also die Funktion "quadrieren" und logge so die Aufrufe. Dies funktioniert genau nach meiner Vorstellung.
Nun habe ich ein weiteres Beispiel mit zwei Klassen erstellt. Die erste heisst MyList und ist hier nicht weiter von Belang. MyListSub erbt von MyList und überschreibt die Methode __add__ (Operator +). Hierbei delegiere ich die Aufrufe nur nach oben, die Methode soll zudem geloggt werden. MyListSub sieht dann so aus:
mylist.py
Schön und gut, die Ausgabe sieht dann weniger erfreulich aus:
Das __add__ an x wird einmal geloggt - es gibt ja auch nur einen Aufruf. Das __add__ an y müsste doch dreimal geloggt werden, füge ich doch auch dreimal ein Zeichen an! Wie man sieht, enthält y danach alle angefügten Zeichen, das Logging hat aber nur einmal stattgefunden (beim Ersten Aufruf mit dem Anfügen von 'b').
Was mache ich falsch?
Ich habe mal zwei Beispiele mit Dekoratoren geschrieben, das erste (einfachere) funktioniert perfekt:
quadrieren.py
Code: Alles auswählen
def log(func):
def wrapper(*args):
print '[ Log: Aufruf von', func, ']'
return func(*args)
return wrapper
@log
def quadrieren(x):
return x ** 2
print quadrieren(1)
print quadrieren(2)
print quadrieren(3)
Code: Alles auswählen
[ Log: Aufruf von <function quadrieren at 0xb7dd2374> ]
1
[ Log: Aufruf von <function quadrieren at 0xb7dd2374> ]
4
[ Log: Aufruf von <function quadrieren at 0xb7dd2374> ]
9
Nun habe ich ein weiteres Beispiel mit zwei Klassen erstellt. Die erste heisst MyList und ist hier nicht weiter von Belang. MyListSub erbt von MyList und überschreibt die Methode __add__ (Operator +). Hierbei delegiere ich die Aufrufe nur nach oben, die Methode soll zudem geloggt werden. MyListSub sieht dann so aus:
mylist.py
Code: Alles auswählen
from mylist import MyList
class MyListSub(MyList):
def __init__(self, data):
MyList.__init__(self, data)
def log(func):
def wrapper(*args):
print '[Log: Call method %s on MyListSub]' % str(func)
print '[Log: Parameter-data: %s]' % str(args)
return func(*args)
return wrapper
@log
def __add__(self, other):
return MyList.__add__(self, other)
if __name__ == '__main__':
x = MyListSub('spam')
x += ['!']
y = MyListSub('foo')
y += ['b']
y += ['a']
y += ['r']
Code: Alles auswählen
[Log: Call method <function __add__ at 0x888a684> on MyListSub]
[Log: Parameter-data: (['s', 'p', 'a', 'm'], ['!'])]
[Log: Call method <function __add__ at 0x888a684> on MyListSub]
[Log: Parameter-data: (['f', 'o', 'o'], ['b'])]
>>> y
['f', 'o', 'o', 'b', 'a', 'r']
>>>
Was mache ich falsch?