¿Cómo obtener el nombre de los parámetros reales de la función en Python?

Por ejemplo:

def func(a): # how to get the name "x" x = 1 func(x) 

Si uso el módulo de inspect , puedo obtener el objeto de marco de stack:

 import inspect def func(a): print inspect.stack() 

afuera:

 [ (, 'ts.py', 9, 'func', [' stack = inspect.stack()\n'], 0) (, 'ts.py', 18, '', ['func(x)\n'], 0) ] 

o use inspect.currentframe() Puedo obtener el marco actual.

Pero solo puedo obtener el nombre "a" inspeccionando el objeto de función.

Utilice inspect.stack . inspect.stack Puedo obtener la stack de llamadas: "['func(x)\n']" ,

¿Cómo puedo obtener el nombre de los parámetros reales ( "x" aquí) al llamar a la func analizando "['func(x)\n']" ?

Si llamo func(x) entonces obtengo "x"

si llamo func(y) entonces obtengo "y"

Editar:

Un ejemplo:

 def func(a): # Add 1 to acttual parameter ... x = 1 func(x) print x # x expected to 2 y = 2 func(y) print y # y expected to 3 

Mirando las explicaciones de sus comentarios, la razón por la que intenta hacer esto es:

Porque quiero impulsar Parámetros de Referencia como en C ++

No puedes hacer eso. En Python, todo se pasa por valor, pero ese valor es una referencia al objeto que se pasa. Ahora, si ese objeto es mutable (como una lista), puede modificarlo, pero si es inmutable, se crea y establece un nuevo objeto. En su ejemplo de código, x es un int que es inmutable, por lo que si desea cambiar el valor de x it, simplemente devuelva su nuevo valor de la función que está invocando:

 def func(a): b = 5 * a # ... some math return b x = 1 x = func(x) 

Entonces, ¿qué pasa si quieres devolver varios valores? ¡Usa una tuple !

 def func(a, b): a, b = 5 * b, 6 * a # ... return b, a a, b = 2, 3 a, b = func(a, b) 

Eso es factible, hasta cierto punto, pero no obstante, es inútil en cualquier tipo de “código real”. Puedes usarlo para hacer trucos de magia en el patio trasero:

Simplemente recupere el stack_frame de llamada como lo está haciendo, luego recorra las variables disponibles en el marco de llamada para obtener una que haga referencia al mismo objeto que obtuvo como parámetro. Las variables están en los diccionarios f_locals y f_globals que son atributos del objeto frame.

Por supuesto, el parámetro pasado puede no estar en un nombre de variable para comenzar: puede ser una constante en la persona que llama, o puede estar dentro de un dict o una lista.

De cualquier manera, como @Nasser lo puso en la respuesta: no es la forma en que funciona Python. Los objetos existen en la memoria, y los nombres de las variables, en cada ámbito, solo apuntan a esos objetos. Los nombres en sí mismos no tienen sentido de lo contrario.

 import inspect from itertools import chain def magic(x): # note that in Python2, 'currentframe' could get a parameter # to indicate which frame you want on the stack. Not so in Python3 fr = inspect.currentframe().f_back for var_name, value in chain(fr.f_locals.items(), fr.f_globals.items()): if value is x: print ("The variable name in the caller context is {}".format(var_name)) def caler(): y = "My constant" magic(y) 

usar listas como referencias

 def func(a): a[0] = a[0] + 1 x = [1] func(x) print x[0] # x expected to 2 y = [2] func(y) print y[0] # y expected to 3 

Esta es mi solución final. Use ast para analizar la instrucción de función y obtener los argumentos:

 import inspect import re import ast def func(a,b,c): stack = inspect.stack() stack_pre = stack[1] function_call_string = ';'.join( stack_pre[4] ).strip('\n') ret = re.search(r'(%s[ ]*\(.*\))' % func.func_name, function_call_string) striped_function_call_string = ret.group() parser = ast.parse(striped_function_call_string) frame = inspect.currentframe() for arg in parser.body[0].value.args: iter_frame = frame.f_back while iter_frame: if arg.id in iter_frame.f_locals: iter_frame.f_locals[arg.id] += 1 break iter_frame = iter_frame.f_back x=1;y=2;z=3;func(x,y,z) print x,y,z 

Fuera: 2 3 4