Hallo zusammen,
kann mir den jemand sagen, welchen Vorteil ich habe wenn ich einen Decorator einsetze und in welchen Fällen in diesen einsetzen sollte. Ich hätte z.B. zur Zeit einen Fall, bei dem ich eine bereits definierte Funktion habe, und diese Funktion würde ich gerne modifizieren, diese sollte aber trotzdem unter dem gleichen Namen laufen, das kann ich aber mit einem Decorator nicht lösen, denn einen Decorator nutze ich doch bei der Erstellung der Funktion oder?
Mein Beispiel:
Ursprungsfunktion --> object.save() --> Das Objekt wird gespeichert
Nach dem Modifizieren der bestehenden Funktion „save()“ sollte diese trotzdem mit object.save() aufgerufen werden. Kann ich sowas mit Decoratoren lösen?
Gruß
Samid
Python Decorators
@samid: Meinst Du sowas?
Code: Alles auswählen
In [1]: def about_to_bark(f):
...: def wrapper(*args):
...: print 'dog about to bark: ' + args[0].nick
...: return f(*args)
...: return wrapper
...:
In [2]: class Dog(object):
...: def __init__(self, nick):
...: self.nick = nick
...: @about_to_bark
...: def bark(self):
...: print 'Woof woof!'
...:
In [3]: dog = Dog('Snoopie')
In [4]: dog.bark()
dog about to bark: Snoopie
Woof woof!
Genau hier ist ja auch der Knackpunkt, du verwendest den Decorator bei der Erstellung einer neuen Funktion. Wie gehe ich aber vor wenn die Funktion bereits
definiert ist, und ich diese bestehende Funktion modifizieren will, dann aber die mod. Funktion mit demselben Namen aufrufe?
definiert ist, und ich diese bestehende Funktion modifizieren will, dann aber die mod. Funktion mit demselben Namen aufrufe?
Ein Decorator ist nichts anderes als eine Funktion, du kannst den daher auch genau so benutzen:
Das Ergebnis des Decorators bindest du einfach an den Namen der alten Methode und schon hast du sie überschrieben.
Code: Alles auswählen
>>> class Spam(object):
... def spam(self, x):
... print x
...
>>> s = Spam()
>>> s.spam(42)
42
>>> def my_fancy_decorator(func):
... def f(self, x):
... return 2*x
... return f
...
>>> Spam.spam = my_fancy_decorator(Spam.spam)
>>> s.spam(42)
84Das Leben ist wie ein Tennisball.
Richtig, die @-Syntax wird dann aber ganz einfach übersetzt. Aus
wird intern
Also nichts anderes als in meinem Beispiel. Vielleicht schaust du dir dazu einfach mal das entsprechende PEP an, da wird noch etwas mehr erläutert.
Code: Alles auswählen
@wrapper
def func(...):
...Code: Alles auswählen
def func(...):
...
func = wrapper(func)Das Leben ist wie ein Tennisball.
