我知道其他一些语言,如PHP,支持“变量变量名”的概念——也就是说,字符串的内容可以用作变量名的一部分。

我听说这通常是一个坏主意,但我认为它可以解决我的Python代码中的一些问题。

在Python中可以做这样的事情吗?会出什么问题?


如果您只是试图通过名称查找现有变量,请参见如何通过(字符串)名称选择变量。但是,首先考虑是否可以按照这个问题中的建议重新组织代码以避免这种需要。


当前回答

您也可以使用collections模块中的namedtuple来代替字典,这使得访问更容易。

例如:

# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])

# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
v = Variables(34, 45)
print(v.first, v.second)

其他回答

您也可以使用collections模块中的namedtuple来代替字典,这使得访问更容易。

例如:

# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])

# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
v = Variables(34, 45)
print(v.first, v.second)

使用globals()(免责声明:这是一个糟糕的做法,但这是对您的问题最直接的回答,请使用其他数据结构作为接受的答案)。

实际上,您可以动态地将变量分配给全局作用域,例如,如果您想要在全局作用域中访问10个变量i_1, i_2…i_10:

for i in range(10):
    globals()['i_{}'.format(i)] = 'a'

这将给所有这10个变量赋值“a”,当然你也可以动态地改变这个值。所有这些变量现在都可以像其他全局声明的变量一样访问:

>>> i_5
'a'

setattr()方法设置指定对象的指定属性的值。

语法是这样的-

setattr(object, name, value)
Example –

setattr(self,id,123)

它等价于self。Id = 123

正如您可能已经观察到的,setattr()期望将一个对象与值一起传递,以生成/修改一个新属性。

我们可以将setattr()与一个解决方案一起使用,以便能够在模块中使用。这里怎么——

import sys
x = "pikachu"
value = 46
thismodule = sys.modules[__name__]
setattr(thismodule, x, value)
print(pikachu)

SimpleNamespace类可以使用setattr或SimpleNamespace的子类来创建新属性,并创建自己的函数来添加新的属性名(变量)。

from types import SimpleNamespace

variables = {"b":"B","c":"C"}
a = SimpleNamespace(**variables)
setattr(a,"g","G")
a.g = "G+"
something = a.a

我已经尝试了python 3.7.3,你可以使用globals()或vars()

>>> food #Error
>>> milkshake #Error
>>> food="bread"
>>> drink="milkshake"
>>> globals()[food] = "strawberry flavor"
>>> vars()[drink] = "chocolate flavor"
>>> bread
'strawberry flavor'
>>> milkshake
'chocolate flavor'
>>> globals()[drink]
'chocolate flavor'
>>> vars()[food]
'strawberry flavor'

参考: https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936