Lo que estás pidiendo no tiene sentido.
variables locales de una función no tienen valores todo el tiempo. Considere esta función:
def foo(x):
y = x + 27
return y
¿Cuál es el valor de la variable local y
foo
's? No puede responder, la pregunta ni siquiera tiene sentido hasta que llame al foo
(e incluso entonces, no hasta que se ejecute la línea y = x + 27
).
E incluso entonces no es lo que y
que no tenga un valor en este momento, podría haber cualquier número de "en vuelo" ejecuciones de foo
. Podría haber subprocesos ejecutando foo
, o foo
podría ser recursivo (posiblemente indirectamente) para que haya más de una llamada en progreso incluso en una única pila de llamadas. O foo
podría ser un generador, por lo que podría haber muchas ejecuciones en vuelo foo
incluso sin recurrencia (es decir,no todos son accesibles desde el alcance más externo foo
). Entonces, ¿cuál y
obtendría el valor de?
El valor de y
en foo
simplemente no es un concepto bien definido a menos que usted esté hablando dentro del alcance de foo
.
Dada la flexibilidad de Python, estoy bastante seguro de que es posible hacer pila marco de la introspección y encontrar un marco de pila para foo
cuando no se vive actualmente y tire de los valores de sus variables locales en ese momento. Esto sería bastante difícil (si no imposible) de hacer con un decorador, porque (a menos que foo
sea un generador) el decorador solo puede agregar el código de envoltura "alrededor" foo
, lo que significa que el código controlado por el decorador se ejecuta antes y después de foo
, por lo que solo obtiene el control cuando el marco de pila foo
no existe.
No voy a dar consejos específicos sobre cómo hacerlo, porque no sé cómo hacerlo. Sin embargo, parece que es casi una mala idea, a menos que esté escribiendo un depurador.
que funciona. Sin embargo, estoy de acuerdo en que es una mala idea, pero estaba interesado en ver si es posible. – Harel
Gran truco. Estoy haciendo un depurador que tiene que atrapar a escondidas internos de una función decorada y para eso es legítimamente útil. Una cosa a tener en cuenta es que se llama tracer() no solo al retorno de la función decorada, sino también a los retornos de todas las funciones llamadas desde dentro de esa función. Como la función decorada siempre tiene el último retorno (y, por lo tanto, establece _locales por última vez) no importa en este caso. – Peter