¿Cómo creo variables variables?
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.
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 , append
y otras operaciones que requerirían una administración de claves incómoda con un dictado.
Utilice la función incorporada getattr
para 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'
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 getattr
o almacenar sus variables en un diccionario y luego acceder a ellas por su nombre.
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 list
tambié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 list
y 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 list
para una secuencia de objetos similares, a set
para una bolsa de objetos ordenados arbitrariamente o a dict
para una bolsa de nombres con valores asociados.