Seite 1 von 1

Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 15:53
von samid
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

Re: Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 16:11
von jerch
@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!

Re: Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 16:16
von samid
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?

Re: Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 16:25
von EyDu
Ein Decorator ist nichts anderes als eine Funktion, du kannst den daher auch genau so benutzen:

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)
84
Das Ergebnis des Decorators bindest du einfach an den Namen der alten Methode und schon hast du sie überschrieben.

Re: Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 16:33
von samid
Super, genau das habe ich gesucht. Danke.
Aber den Syntaxausdruck:

@wrapper
.....

kann ich nur bei der Bildung einer neuen Funktion verwenden?

Re: Python Decorators

Verfasst: Donnerstag 16. Januar 2014, 16:56
von EyDu
Richtig, die @-Syntax wird dann aber ganz einfach übersetzt. Aus

Code: Alles auswählen

@wrapper
def func(...):
    ...
wird intern

Code: Alles auswählen

def func(...):
    ...

func = wrapper(func)
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.