¿Obteniendo referencias a objetos de función en la pila de ejecución del objeto frame?
-
06-07-2019 - |
Pregunta
Dada la salida de inspect.stack ()
, ¿es posible obtener los objetos de función desde cualquier lugar del marco de la pila y llamarlos? Si es así, ¿cómo?
(Ya sé cómo obtener los nombres de las funciones).
Esto es a lo que me refiero: ¿Digamos que soy una función y estoy tratando de determinar si mi persona que llama es un generador o una función normal? Necesito llamar a inspect.isgeneratorfunction ()
en el objeto de función. ¿Y cómo sabes quién te llamó? inspect.stack ()
, ¿verdad? Entonces, si de alguna manera puedo juntarlos, tendré la respuesta a mi pregunta. ¿Quizás hay una manera más fácil de hacer esto?
Solución
Aquí hay un fragmento de código que lo hace. No hay verificación de errores. La idea es encontrar en los locales del gran padre el objeto de función que se llamó. El objeto de función devuelto debe ser el padre. Si desea buscar también las construcciones integradas, simplemente busque en las pilas [2] [0] .f_builtins.
def f():
stacks = inspect.stack()
grand_parent_locals = stacks[2][0].f_locals
caller_name = stacks[1][3]
candidate = grand_parent_locals[caller_name]
En el caso de una clase, se puede escribir lo siguiente (inspirado en la solución de Marcin)
class test(object):
def f(self):
stack = inspect.stack()
parent_func_name = stack[1][3]
parent_func = getattr(self, parent_func_name).im_func
Otros consejos
Tomé el siguiente enfoque, muy similar a la respuesta de Eolmar.
stack = inspect.stack()
parent_locals = stack[1][0].f_locals['self']
parent_func_name = stack[1][3]
parent_func_attr = getattr(parent_locals,parent_func_name)
parent_func = parent_func_attr.im_func
is_parent_gen = inspect.isgeneratorfunction(func)