Wie Original-Argumente von dekorierter Funktion anzeigen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Zur Erstellung eines Dekorators verwende ich das typische Idiom mit functools.wraps():

Code: Alles auswählen

>>> def my_decorator(f):
...     @wraps(f)
...     def wrapper(*args, **kwds):
...         print 'Calling decorated function'
...         return f(*args, **kwds)
...     return wrapper
...
>>> @my_decorator
... def example():
...     """Docstring"""
...     print 'Called example function'
Ruft man ein `help()` oder bei IPython das Fragezeichen für die dekorierte Funktion auf, dann erscheint auch erwartungsgemäß der Original-Docstring und der Original-Name der Funktion in der Signatur. Was aber fehlt, sind die Original-Argumente. Stattdessen steht dort nur `(*args, **kwds)`.

Wie bekomme ich es also hin, dass `functools.wraps()` auch die Argumente korrekt übernimmt? Oder anders: Was muss ich den `WRAPPER_ASSIGNMENTS` anfügen, damit es funktioniert?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Anscheinend doch nicht so trivial. Ich werde mich wohl am Quellcode des decorator-Moduls orientieren. Dort passieren die für mich relevanten Dinge offenbar in der `update`-Methode des `FunctionMaker`s. Auf dieser Grundlage schreibe ich mir dann halt meinen eigenen Wrapper-Dekorator, der auch wirklich möglichst alles wrappt. Für die paar Zeilen möchte ich nicht unbedingt das besagte Paket zur Abhängigkeit machen. Melde mich dann wahrscheinlich nochmal, wenn der Dekorator fertig ist. :)
lunar

@snafu: Ist doch Blödsinn, seine eigene Lösung zu erfinden, wenn es eine perfekte Lösung bereits gibt. Zumal es mit ein paar Zeilen nicht getan ist, da "decorator" im Wesentlichen Quelltext erzeugen und kompilieren muss, um die Signatur der dekorierten Funktion in den Dekorator zu übernehmen, da die Signaturen von Funktionsobjekten in CPython unveränderlich sind.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

lunar hat geschrieben:[...] da die Signaturen von Funktionsobjekten in CPython unveränderlich sind.
Achso, das hatte ich nicht bedacht bzw wusste es nicht. Ich war schon verwundert, wieso im `decorator`-Quelltext noch soviel drumherum gemacht wird.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Jo, finde das decorator-Modul, nein, falsch, die Funktionalität sollte in functools aufgenommen werden. Weil so sind Dekoratoren etwas verkrüppelt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Leonidas hat geschrieben:Jo, finde das decorator-Modul, nein, falsch, die Funktionalität sollte in functools aufgenommen werden. Weil so sind Dekoratoren etwas verkrüppelt.
Find ich irgendwie auch. Möglicherweise kann man schon direkt an der Implementierung in CPython was machen, denn als sauber würde ich die Lösung, die `decorator` geht, nicht unbedingt bezeichnen. Wird aber vermutlich seinen Sinn haben, warum das mit der Unveränderlichkeit der Argumente (oder besser gesagt: der Signatur) so geregelt ist. Evtl bringt ja hier lunar oder jemand anders Licht ins Dunkel... :)
Antworten