Ich habe mir ein einfaches Event-System in Python gemacht, und ich fand, dass die Art und Weise, wie ich die Ereignisse abfeuerte, jedes Mal ziemlich gleich war: entweder am Ende eines Anrufs oder davor. Es fühlte sich an, als wäre es eine schöne Sache, als Dekorateur zu haben. Hier ist der Code Ich verwende:Kann ich eine Eigenschaft des Ergebnisses einer Funktion als Dekorator verwenden?
from functools import wraps
def fires(event):
"""
Returns a decorater that causes an `Event` to fire immediately before the
decorated function is called
"""
def beforeDecorator(f):
"""Fires the event before the function executes"""
@wraps(f)
def wrapped(*args, **kargs):
event.fire(*args, **kargs)
return f(*args, **kargs)
return wrapped
def afterDecorator(f):
"""Fires the event after the function executes"""
@wraps(f)
def wrapped(*args, **kargs):
result = f(*args, **kargs)
event.fire(*args, **kargs)
return result
return wrapped
# Should allow more explicit `@fires(event).uponCompletion` and
# `@fires(event).whenCalled`
afterDecorator.onceComplete = afterDecorator
afterDecorator.whenCalled = afterDecorator
return afterDecorator
Mit diesem Code kann ich dies erfolgreich schreiben:
@fires(myEvent)
def foo(y):
return y*y
print func(2)
Und alles funktioniert. Das Problem kommt, wenn ich versuche, dies zu schreiben:
@fires(myEvent).onceComplete
def foo(y):
return y*y
print func(2)
Das gibt mir einen Syntaxfehler. Gibt es eine spezielle Syntax für komplexe Dekoratoren? Stoppt der Parser nach der ersten Klammer?
Nicht nur jeder Ausdruck kann als Dekorateur verwendet werden. Zum Beispiel funktioniert '@ (Lambda f: f())' nicht. – wberry