Me gustaría poder obtener el nombre de una variable como una cadena, pero no sé si Python tiene tanta capacidad de introspección. Algo como:
>>> print(my_var.__name__)
'my_var'
Quiero hacer eso porque tengo un montón de variables que me gustaría convertir en un diccionario como:
bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict
{'foo': False, 'bar': True}
Pero me gustaría algo más automático que eso.
Python tiene locals()
y vars()
, así que supongo que hay una manera.
Respuestas:
¿Estás tratando de hacer esto?
Ejemplo
fuente
print('x: ' + x)
uno pueda escribirmagic_print(x)
y tener la misma salida sin escribir el nombre de la variable dos veces.Como dijimos, esto no es realmente algo que se hace en Python: las variables son en realidad asignaciones de nombres a objetos.
Sin embargo , aquí hay una forma de intentarlo:
fuente
True
), podría devolverse un nombre de variable no deseado.id(v) == id(a)
lugar dev is a
? Esto fallará para los objetos vinculados a múltiples variables, como ints, cadenas y cualquier tipo definido por el usuario implementado de manera similar.v is a
sería una mejor opción. ¡Y sí, ciertamente peligroso, dadas todas las trampas potenciales que podrían surgir! ;-)He querido hacer esto bastante. Este truco es muy similar a la sugerencia de rlotun, pero es una frase, lo cual es importante para mí:
Python 3+
fuente
iteritems()
se reemplaza poritems()
spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)
Salidasspam
spam = 1, blah = 1; assert spam is blah
. La solución se rompe al comparar tipos de datos primitivos.Este es un truco. No funcionará en todas las distribuciones de implementaciones de Python (en particular, aquellas que no tienen
traceback.extract_stack
).Tenga en cuenta que este truco es frágil:
(llamando a make_dict en 2 líneas) no funcionará.
En lugar de tratar de generar el dict a partir de los valores
foo
ybar
, sería mucho más Pythonic generar el dict a partir de los nombres de las variables de cadena'foo'
y'bar'
:fuente
print("a_very_long_name: {}'.format(a_very_long_name))
quién le importa.Esto no es posible en Python, que realmente no tiene "variables". Python tiene nombres, y puede haber más de un nombre para el mismo objeto.
fuente
Creo que mi problema ayudará a ilustrar por qué esta pregunta es útil, y puede dar un poco más de información sobre cómo responderla. Escribí una pequeña función para hacer una verificación rápida de la cabeza en línea en varias variables en mi código. Básicamente, enumera el nombre de la variable, el tipo de datos, el tamaño y otros atributos, para que pueda detectar rápidamente cualquier error que haya cometido. El código es simple:
Entonces, si tiene una situación complicada de diccionario / lista / tupla, sería muy útil que el intérprete le devuelva el nombre de la variable que asignó. Por ejemplo, aquí hay un diccionario extraño:
No estoy seguro si puse esto en el lugar correcto, pero pensé que podría ayudar. Espero que si.
fuente
myconnection
podría apuntar a un valor booleano en un punto, un número entero en otro momento y una conexión de socket en otro punto en la ejecución del código?Escribí una función útil poco útil basada en la respuesta a esta pregunta. Lo pongo aquí en caso de que sea útil.
uso:
fuente
Me parece que si ya tiene una lista específica de valores, esa es la forma descrita por @S. Lotts es el mejor; sin embargo, la forma descrita a continuación funciona bien para obtener todas las variables y clases agregadas en todo el código SIN la necesidad de proporcionar el nombre de la variable, aunque puede especificarlas si lo desea. El código se puede extender para excluir clases.
Salida:
fuente
En python 3 esto es fácil
esto imprimirá:
fuente
for v in locals()
.for v in list(locals()):
Python3. Use inspeccionar para capturar el espacio de nombres local que llama y luego use las ideas presentadas aquí. Puede devolver más de una respuesta como se ha señalado.
fuente
Aquí está la función que creé para leer los nombres de las variables. Es más general y se puede usar en diferentes aplicaciones:
Para usarlo en la pregunta especificada:
fuente
Al leer el hilo, vi mucha fricción. Es bastante fácil dar una mala respuesta y luego dejar que alguien dé la respuesta correcta. De todos modos, esto es lo que encontré.
De: [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )
Los nombres son un poco diferentes: en realidad no son propiedades del objeto, y el objeto en sí no sabe cómo se llama.
Un objeto puede tener cualquier cantidad de nombres, o ningún nombre.
Los nombres viven en espacios de nombres (como un espacio de nombres de módulo, un espacio de nombres de instancia, el espacio de nombres local de una función).
Nota: dice que el objeto en sí no sabe cómo se llama , así que esa era la pista. Los objetos de Python no son autorreferenciales. Luego dice: los nombres viven en espacios de nombres . Tenemos esto en TCL / TK. Entonces, tal vez mi respuesta ayude (pero sí me ayudó)
Entonces hay 'jj' al final de la lista.
Reescribe el código como:
Este desagradable código de identificación de código se llama variable / object / whatever-you-pedantics-call-it.
Entonces, ahí está. La dirección de memoria de 'jj' es la misma cuando la buscamos directamente, como cuando buscamos el diccionario en el espacio de nombre global. Estoy seguro de que puedes hacer una función para hacer esto. Solo recuerde en qué espacio de nombres se encuentra su variable / objeto / wypci.
QED
fuente
print id(jj)
. El segundo simplemente busca el nombre y se puede hacer más fácilmentevars()
.Tal vez estoy pensando demasiado en esto pero ...
fuente
variable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
fuente
Subí una solución a pypi . Es un módulo que define un equivalente de la
nameof
función de C # .Se itera a través de instrucciones de código de bytes para el marco al que se llama, obteniendo los nombres de variables / atributos que se le pasan. Los nombres se encuentran en el
.argrepr
deLOAD
instrucciones siguiente nombre de la función.fuente
Escribí el paquete de brujería para hacer este tipo de magia de manera robusta. Puedes escribir:
fuente
La mayoría de los objetos no tienen un atributo __name__ . (Las clases, funciones y módulos sí; ¿hay más tipos incorporados que tengan uno?)
¿Qué más esperarías para que
print(my_var.__name__)
no seaprint("my_var")
? ¿Puedes simplemente usar la cadena directamente?Podrías "cortar" un dict:
Alternativamente:
fuente
some_func(var)
, así que traté de señalar que no está muy lejossome_func("var")
, con dictslice que te permite obtener la asignación de nombre-valor para múltiples variables a la vez.Bueno, hace unos días me encontré con la misma necesidad y tuve que obtener el nombre de una variable que apuntaba al objeto en sí.
¿Y por qué era tan necesario?
En resumen, estaba construyendo un complemento para Maya . El complemento central se creó con C ++, pero la GUI se dibuja a través de Python (ya que no requiere un procesador intensivo). Como todavía no sé cómo hacer
return
múltiples valores desde el complemento, excepto el predeterminadoMStatus
, por lo tanto, para actualizar un diccionario en Python, tuve que pasar el nombre de la variable, señalando el objeto que implementa la GUI y cuál contenía el diccionario en sí, para el complemento y luego usaMGlobal::executePythonCommand()
para actualizar el diccionario desde el alcance global de Maya .Para hacer eso, lo que hice fue algo como:
Sé que no es la solución perfecta, ya que
globals
muchas de las teclas podrían estar apuntando al mismo objeto, por ejemplo:y que el enfoque no es seguro para subprocesos. Corrígeme si estoy equivocado.
Al menos este enfoque resolvió mi problema al obtener el nombre de cualquier variable en el ámbito global que apuntara al objeto en sí mismo y pasarlo al complemento, como argumento, para su uso interno.
Probé esto en
int
(la clase entera primitiva) pero el problema es que estas clases primitivas no se omiten (corrija la terminología técnica utilizada si es incorrecta). Puede volver a implementarint
y luego hacerint = foo
peroa = 3
nunca serás objeto defoo
sino de lo primitivo. Para superar eso tienesa = foo(3)
que ponertea.name()
a trabajar.fuente
Con Python 2.7 y versiones posteriores también hay comprensión del diccionario, lo que lo hace un poco más corto. Si fuera posible, usaría getattr en su lugar eval (eval es malvado) como en la respuesta superior. Self puede ser cualquier objeto que tenga el contexto que estás mirando. Puede ser un objeto o locales = locales () etc.
fuente
Estaba trabajando en un problema similar. @ S.Lott dijo "Si tienes la lista de variables, ¿cuál es el punto de" descubrir "sus nombres?" Y mi respuesta es solo para ver si se puede hacer y si por alguna razón desea ordenar sus variables por tipo en listas. De todos modos, en mi investigación me encontré con este hilo y mi solución se amplió un poco y se basa en la solución @rlotun. Otra cosa, dijo @unutbu, "esta idea tiene mérito, pero tenga en cuenta que si dos nombres de variables hacen referencia al mismo valor (por ejemplo, True), podría devolverse un nombre de variable no deseado". En este ejercicio que era verdad lo que se ocuparon de ello mediante el uso de una lista por comprensión similar a esto para cada posibilidad:
isClass = [i for i in isClass if i != 'item']
. Sin él, el "elemento" aparecería en cada lista.fuente
pi = pie
a su código, obtendría una entrada adicional en suisFloat
lista. Si agregótuple_1[0]
a sumixedDataTypes
lista, no se encontrará ningún nombre para él a pesar de que "uno" esté en su código dos veces (aunque gracias a la secuencia interna, ambos serán referencias al mismo objeto).pi
ye
como variables causaba resultados no deseados y eso es porque ambos son parte de lamath
biblioteca. Para mí esto fue solo un ejercicio para ver si se podía hacer a pesar de que el resultado final no es perfecto. En mi aprendizaje de este idioma, leer libros solo llega hasta cierto punto. En mi opinión, si realmente quieres aprender el idioma, tienes que jugar "qué pasaría si" y ver qué se te ocurre.puedes usar easydict
otro ejemplo:
fuente
En python3, esta función obtendrá el nombre más externo en la pila:
Es útil en cualquier parte del código. Atraviesa la pila invertida buscando el primer partido.
fuente
Si bien esta es probablemente una idea horrible, está en la misma línea que la respuesta de rlotun, pero devolverá el resultado correcto con mayor frecuencia.
Lo llamas así:
fuente
debería obtener la lista y luego regresar
fuente
No devolverá el nombre de la variable, pero puede crear fácilmente un diccionario a partir de una variable global.
fuente
Con
python-varname
usted puede hacerlo fácilmente:pip install python-varname
Descargo de responsabilidad: soy el autor de esa biblioteca python-varname.
fuente
de esta forma, obtenga varname para quizás 'a' o 'b'.
fuente