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

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

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


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


当前回答

我回答的问题如何得到一个变量的值给定它的名字在一个字符串? 这是一个带有问题链接的副本。(编者注:它现在被关闭为“如何通过(字符串)名称选择变量?”的副本?)


如果所讨论的变量是对象的一部分(例如类的一部分),则可以使用hasattr、getattr和setattr函数来实现这一点。

例如,你可以有:

class Variables(object):
    def __init__(self):
        self.foo = "initial_variable"

    def create_new_var(self, name, value):
        setattr(self, name, value)

    def get_var(self, name):
        if hasattr(self, name):
            return getattr(self, name)
        else:
            raise "Class does not have a variable named: " + name

然后你可以这样做:

>>> v = Variables()
>>> v.get_var("foo")
'initial_variable'
>>> v.create_new_var(v.foo, "is actually not initial")
>>> v.initial_variable
'is actually not initial'

其他回答

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

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或将变量存储在字典中,然后按名称访问它们。

你必须使用globals()内置方法来实现这种行为:

def var_of_var(k, v):
    globals()[k] = v

print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print(variable_name) # 123

some_name = 'variable_name2'
var_of_var(some_name, 456)
print(variable_name2) # 456

您可以使用字典来实现这一点。字典是键和值的存储。

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

可以使用可变键名实现可变变量的效果,而不存在安全风险。

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

如果你想做些什么

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

清单可能比字典更合适。list表示对象的有序序列,索引为整数:

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

对于有序序列,列表比使用整数键的字典更方便,因为列表支持索引顺序迭代、切片、追加和其他需要使用字典进行笨拙的键管理的操作。