2009-05-31 9 views
26

¿hay alguna forma de saber, durante el tiempo de ejecución, el nombre de una variable (del código)? o se olvidan los nombres de Var durante la compilación (código de bytes o no)?recuperando el nombre de una variable en python en tiempo de ejecución?

p. Ej.

 
>>> vari = 15 
>>> print vari.~~name~~() 
'vari' 

nota: estoy hablando de las variables de fricción de tipo de datos (int, str, lista ...)

+6

¿No tienes que escribir el nombre de la variable para obtener su nombre? –

+2

Sí, bueno, ha sido hace 3 años, y no recuerdo por qué esta pregunta tenía sentido. Pero woa! es extremadamente popular, así que hay algo al respecto. –

+0

Aquí hay un ejemplo de uso: las variables foo, bar, baz están ahí, quiero obtener un diccionario exactamente como {'foo': foo, 'bar': bar, 'baz': baz}. Seguramente puedo escribir como lo que acabo de hacer, pero no muy sucinto. 'locals()', en mi opinión, pasa demasiada información, no es perfecta. Lo que espero es una función como 'magic_func ([foo, bar, baz])' que devuelve el diccionario que quiero – ZZY

Respuesta

2

aquí una función básica (quizás rara) que muestra el nombre de su argumento ... la idea es analizar el código y la búsqueda de las llamadas a la función (añadido en el método init que podría ayudar a encontrar el nombre de la instancia, aunque con un análisis de código más complejo)

def display(var): 
    import inspect, re 
    callingframe = inspect.currentframe().f_back 
    cntext = "".join(inspect.getframeinfo(callingframe, 5)[3]) #gets 5 lines 
    m = re.search("display\s+\(\s+(\w+)\s+\)", cntext, re.MULTILINE) 
    print m.group(1), type(var), var 

tenga en cuenta: conseguir múltiples líneas del código de llamada ayuda en caso de que la llamada se dividió como en el siguiente ejemplo:

display(
     my_var 
     ) 

pero producirá resultado inesperado en esto:

display(first_var) 
display(second_var) 

Si no tiene control sobre el formato de su proyecto todavía se puede mejorar el código para detectar y manejar diferentes situaciones ...

general supongo que un análisis de código estático podría producir un resultado más fiable, pero soy muy vago para verificarlo ahora

10

Los nombres de variables persisten en el código compilado (así por ejemplo, el dir incorporado puede trabajo), pero la asignación que está allí va de nombre a valor, no al revés. Entonces, si hay varias variables que valen la pena, por ejemplo, 23, no hay forma de contarlas desde otra base solo en el valor 23.

29

Los nombres de las variables no se olvidan, puede acceder a las variables (y ver qué variables tiene) por introspección, p. Ej.

>>> i = 1 
>>> locals()["i"] 
1 

Sin embargo, porque no hay punteros en Python, no hay manera de hacer referencia a una variable sin escribir su nombre. Por lo tanto, si desea imprimir un nombre de variable y su valor, puede ir a través del locals() o una función similar. ([i] convierte [1] y no hay manera de recuperar la información que el 1 en realidad procedían de i.)

+0

, esto resuelve mi caso. luego hago una búsqueda inversa de sus valores y encuentro sus nombres. Gracias. –

+5

La parte difícil de esto es que si solo tienes 'i ', entonces es imposible encontrar su nombre en' locals() '. Considera 'i = 1; j = 1; '. Después de esto, 'locals() ["i"] es locals() ["j"]'. Si todo lo que tienes es 'i ', al pasar por locals() obtendrás' i 'o' j 'como nombre. –

+1

D. probablemente tenga la intención de decir "Si todo lo que tienes es' 1' [...] " – akaihola

0

Ayer vi un post con el código que hace precisamente este trabajo. Aquí está el enlace:

http://pyside.blogspot.com/2009/05/finding-objects-names.html

+0

" Lo sentimos, la página que estabas buscando en este blog no existe. " –

+2

@StuartWoodward: archive.org tiene una copia: http://web.archive.org/web/20090624235438/http://pyside.blogspot.com/2009/05/finding-objects-names.html –

+0

Va a también solo funciona en su forma actual si se usa en el archivo python 'main'; si se importa, abrirá el archivo incorrecto, por lo que deberá adaptarse. – will

3

Esto funciona para los tipos de datos simples (str, int, float, etc. lista)

def my_print(var_str) : 
    print var_str+':', globals()[var_str] 
+0

Solo necesita tener en cuenta que, si tiene, digamos 'ix = 200', entonces llama a esta función con' my_print ("ix") '. – sdaau

4

Aquí es una función que utilizo para imprimir el valor de las variables, funciona para locales, así como globales:

import sys 
def print_var(var_name): 
    calling_frame = sys._getframe().f_back 
    var_val = calling_frame.f_locals.get(var_name, calling_frame.f_globals.get(var_name, None)) 
    print (var_name+':', str(var_val)) 

así que el siguiente código:

global_var = 123 
def some_func(): 
    local_var = 456 
    print_var("global_var") 
    print_var("local_var") 
    print_var("some_func") 

some_func() 

produce:

global_var: 123 
local_var: 456 
some_func: <function some_func at 0x10065b488> 
+0

Esto es lo que estaba buscando. Sin embargo, ahora tengo curiosidad si esto se puede expandir para que funcione con cualquier expresión dado el contexto de cuándo se llama a 'print_var'. Un caso de uso sería imprimir tanto el nombre como el valor de un campo de un objeto (p. Ej., 'Print_var ('myobject.x')') – anishpatel

+0

. De hecho, no era demasiado difícil: https://gist.github.com/anishpatel/e32f9cdc1df55692f418 – anishpatel

2

Puede hacerlo, simplemente no es bastante.

import inspect, sys 


def addVarToDict(d, variable): 
    lineNumber = inspect.currentframe().f_back.f_lineno 
    with open(sys.argv[0]) as f: 
     lines = f.read().split("\n") 

    line = lines[lineNumber-1] 

    varName = line.split("addVarToDict")[1].split("(")[1].split(",")[1].split(")")[0].strip() 
    d[varName] = variable 


d = {} 

a=1 

print d # {} 
addVarToDict(d,a) 
print d # {'a': 1} 
Cuestiones relacionadas