Definieren Funktionen in decorator
-
16-09-2019 - |
Frage
Warum funktioniert das nicht? Wie kann ich es? Das heißt, wie kann ich gu zugänglich in meinem dekoriert Funktion machen?
def decorate(f):
def new_f():
def gu():
pass
f()
return new_f
@decorate
def fu():
gu()
fu()
Muss ich gu zu einem Wörterbuch der definierten Funktionen irgendwie hinzufügen müssen? Oder kann ich gu auf dem lokalen Namensraum f hinzufügen, bevor es nennen?
Lösung
Im Prinzip können Sie eine neue Funktion mit dem gleichen Code wie die alten schaffen, sondern die globale Reichweite mit einem ergänzten Substitution ein:
import new
def with_bar(func):
def bar(x):
return x + 1
f_globals = func.func_globals.copy()
f_globals['bar'] = bar
return new.function(func.func_code, f_globals,
func.func_name, func.func_defaults, func.func_closure)
@with_bar
def foo(x):
return bar(x)
print foo(5) # prints 6
In der Praxis sollten Sie wirklich einen besseren Weg finden, dies zu tun. Passing in Funktionen als Parameter ist eine Option. Es könnte auch andere Ansätze, aber es ist schwer zu sagen, was ohne eine High-Level-Problem Beschreibung passen würde.
Andere Tipps
Wenn Sie gu
passieren Sie fu
müssen diese durch Parameter explizit tun:
def decorate(f):
def new_f():
def gu():
pass
f(gu)
return new_f
@decorate
def fu(gu):
gu()
fu()
gu ist lokal auf die new_f Funktion, die lokal auf das deco Funktion.
gu () nur innerhalb new_f definiert (). Sofern Sie es nicht zurückgeben oder Anker new_f () oder etwas anderes, es kann nicht von außen new_f referenziert werden ()
Ich weiß nicht, was du bist, aber dieses Schema scheint sehr komplex. Vielleicht können Sie eine weniger komplizierte Lösung finden.
Warum nicht Ihr Dekorateur eine Klasse machen, anstatt eine Funktion? Es ist offenbar möglich, als ich entdeckte, als ich durch die Hilfe für die property
builtin aussah. (Früher hatte ich gedacht, dass Sie nur Dekorateure Klassen gelten könnten, und nicht, dass die Dekorateure können sich Klassen sein.)
(Natürlich gu
würde eine Methode der Klasse sein oder eine inneren Klasse.)