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

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

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


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


当前回答

如果你不想使用任何对象,你仍然可以在当前模块中使用setattr():

import sys
current_module = module = sys.modules[__name__]  # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15)  # 15 is the value you assign to the var
print(variable_name)  # >>> 15, created from a string

其他回答

这不是个好主意。如果要访问全局变量,可以使用globals()。

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

如果想要访问局部作用域内的变量,可以使用locals(),但不能为返回的dict赋值。

更好的解决方案是使用getattr或将变量存储在字典中,然后按名称访问它们。

这应该是非常危险的…… 但是你可以使用exec():

a = 'b=5'
exec(a)
c = b*2
print (c)

结果: 10

您也可以使用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)

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