¿Cómo creo variables variables?

Resuelto asked hace 15 años • 18 respuestas

Sé que algunos otros lenguajes, como PHP , admiten el concepto de "nombres de variables variables", es decir, el contenido de una cadena se puede utilizar como parte de un nombre de variable.

Escuché que esta es una mala idea en general, pero creo que resolvería algunos problemas que tengo en mi código Python.

¿Es posible hacer algo como esto en Python? ¿Qué puede ir mal?


Si solo está intentando buscar una variable existente por su nombre, consulte ¿Cómo puedo seleccionar una variable por nombre (cadena)? . Sin embargo, primero considere si puede reorganizar el código para evitar esa necesidad, siguiendo los consejos de esta pregunta.

 avatar Sep 03 '09 19:09
Aceptado

Puede utilizar diccionarios para lograr esto. Los diccionarios son almacenes de claves y valores.

>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'x': 1, 'y': 2, 'z': 3}
>>> dct["y"]
2

Puede utilizar nombres de claves de variables para lograr el efecto de las variables variables sin el riesgo de seguridad.

>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'

Para los casos en los que estás pensando en hacer algo como

var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...

una lista puede ser más apropiada que un dictado. Una lista representa una secuencia ordenada de objetos, con índices enteros:

lst = ['foo', 'bar', 'baz']
print(lst[1])           # prints bar, because indices start at 0
lst.append('potatoes')  # lst is now ['foo', 'bar', 'baz', 'potatoes']

Para secuencias ordenadas, las listas son más convenientes que los dictados con claves enteras, porque las listas admiten iteración en el orden del índice, división , appendy otras operaciones que requerirían una administración de claves incómoda con un dictado.

 avatar Sep 03 '2009 12:09

Utilice la función incorporada getattrpara obtener un atributo de un objeto por nombre. Modifique el nombre según sea necesario.

obj.spam = 'eggs'
name = 'spam'
getattr(obj, name)  # returns 'eggs'
SilentGhost avatar Sep 03 '2009 12:09 SilentGhost

No es una buena idea. Si está accediendo a una variable global, puede usar globals().

>>> a = 10
>>> globals()['a']
10

Si desea acceder a una variable en el ámbito local, puede usar locals(), pero no puede asignar valores al dict devuelto.

Una mejor solución es usar getattro almacenar sus variables en un diccionario y luego acceder a ellas por su nombre.

Nadia Alramli avatar Sep 03 '2009 12:09 Nadia Alramli

Los nuevos programadores a veces escriben código como este:

my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...

Luego, el codificador se queda con un montón de variables con nombre, con un esfuerzo de codificación de O ( m * n ), donde m es el número de variables con nombre y n es el número de veces que es necesario acceder a ese grupo de variables (incluida la creación). ). El principiante más astuto observa que la única diferencia en cada una de esas líneas es un número que cambia según una regla y decide utilizar un bucle. Sin embargo, se atascan en cómo crear dinámicamente esos nombres de variables y pueden intentar algo como esto:

for i in range(10):
    my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)

Pronto descubren que esto no funciona.

Si el programa requiere "nombres" de variables arbitrarias, un diccionario es la mejor opción, como se explica en otras respuestas. Sin embargo, si simplemente estás intentando crear muchas variables y no te importa referirte a ellas con una secuencia de números enteros, probablemente estés buscando un archivo list. Esto es particularmente cierto si sus datos son homogéneos, como lecturas de temperatura diarias, puntajes de pruebas semanales o una cuadrícula de widgets gráficos.

Esto se puede montar de la siguiente manera:

my_calculator.buttons = []
for i in range(10):
    my_calculator.buttons.append(tkinter.Button(root, text=i))

Esto listtambién se puede crear en una línea con una comprensión:

my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]

El resultado en cualquier caso es un elemento poblado list, al que se accede al primer elemento con my_calculator.buttons[0], al siguiente con my_calculator.buttons[1], y así sucesivamente. El nombre de la variable "base" se convierte en el nombre de listy el identificador variable se utiliza para acceder a él.

Finalmente, no olvide otras estructuras de datos, como set- esto es similar a un diccionario, excepto que cada "nombre" no tiene un valor adjunto. Si simplemente necesitas una "bolsa" de objetos, esta puede ser una gran elección. En lugar de algo como esto:

keyword_1 = 'apple'
keyword_2 = 'banana'

if query == keyword_1 or query == keyword_2:
    print('Match.')

Tendrás esto:

keywords = {'apple', 'banana'}
if query in keywords:
    print('Match.')

Utilice a listpara una secuencia de objetos similares, a setpara una bolsa de objetos ordenados arbitrariamente o a dictpara una bolsa de nombres con valores asociados.

TigerhawkT3 avatar Aug 16 '2016 10:08 TigerhawkT3