Callable de-dekorieren?

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
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich möchte für eine Web-Applikation Unittests schreiben. Dazu möchte ich nicht mit XHTML-Strings rumdaddeln, sondern die Daten verwenden, die die Action-Callables zurückgeben. Diese sind aber mit einem Decorator gewrappt, der eben diese Daten als Kontext an ein Template übergibt und dann letztlich mehr oder weniger direkt XHTML zurückliefert.

Gibt es einen eleganten Weg um an die dekorierte Callable zu kommen, ohne diese im Dekorator zwischenzuspeichern oder ähnliches. Und ohne die ursprüngliche Callable z.B. als `_some_action` zu definieren und diese in der dekorierten `some_action` aufzurufen? Dann hätte ich nämlich knapp doppelt so viele Definitionen und das wäre irgendwie uncool (und nachträglich viel Arbeit).
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Warum willst du denn keine Referenz vom Decorator zum eigentlichen Callable haben, das ist wahrscheinlich der einfachste Weg?
Benutzeravatar
mq
User
Beiträge: 124
Registriert: Samstag 1. Januar 2005, 19:14

Wenn der Decorator voellig unabhaengig von der dekorierten Funktion arbeitet, wird das denke ich nicht moeglich sein. Wenn er (was der Normalfall ist) eine Funktion definiert, die die dekorierte Funktion aufruft, koennte folgendes dir weiterhelfen:

Code: Alles auswählen

>>> def dec(f):
...  def func(*args, **kwargs):
...   return f(*args, **kwargs) + 1
...  return func
... 
>>> @dec
... def bla():
...  return 42
... 
>>> bla()
43
>>> bla_orig = bla.func_closure[0].cell_contents
>>> bla_orig()
42
>>> 
Ich hab allerdings nicht getestet, in welchen Faellen das funktioniert und in welchen nicht (insbesondere bei komplexeren Dekoratoren), und ich kenn mich mit Closures und Cells im Allgemeinen nicht wirklich aus. Du koenntest hoechstens versuchen, mit Angucken des Bytecodes der vom Decorator zurueckgegebenen Funktion festzustellen, ob die in einem Closure arbeitet (falls ja, wird sie vermutlich den Code LOAD_DEREF enthalten). Nur im oben genannten Fall wird's halt nicht funktionieren. Ganz ohne Referenz kommst du also nicht aus.
Antworten