我知道其他一些语言,如PHP,支持“变量变量名”的概念——也就是说,字符串的内容可以用作变量名的一部分。
我听说这通常是一个坏主意,但我认为它可以解决我的Python代码中的一些问题。
在Python中可以做这样的事情吗?会出什么问题?
如果您只是试图通过名称查找现有变量,请参见如何通过(字符串)名称选择变量。但是,首先考虑是否可以按照这个问题中的建议重新组织代码以避免这种需要。
我知道其他一些语言,如PHP,支持“变量变量名”的概念——也就是说,字符串的内容可以用作变量名的一部分。
我听说这通常是一个坏主意,但我认为它可以解决我的Python代码中的一些问题。
在Python中可以做这样的事情吗?会出什么问题?
如果您只是试图通过名称查找现有变量,请参见如何通过(字符串)名称选择变量。但是,首先考虑是否可以按照这个问题中的建议重新组织代码以避免这种需要。
当前回答
您可以使用字典来实现这一点。字典是键和值的存储。
>>> 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']
对于有序序列,列表比使用整数键的字典更方便,因为列表支持索引顺序迭代、切片、追加和其他需要使用字典进行笨拙的键管理的操作。
其他回答
我已经尝试了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
这不是个好主意。如果要访问全局变量,可以使用globals()。
>>> a = 10
>>> globals()['a']
10
如果想要访问局部作用域内的变量,可以使用locals(),但不能为返回的dict赋值。
更好的解决方案是使用getattr或将变量存储在字典中,然后按名称访问它们。
使用内置的getattr函数按名称获取对象的属性。根据需要修改名称。
obj.spam = 'eggs'
name = 'spam'
getattr(obj, name) # returns 'eggs'
大家的共识是使用字典来进行查询-请参阅其他答案。在大多数情况下,这是一个好主意,然而,这产生了许多方面:
您将自己负责这个字典,包括垃圾收集(indict变量)等。 变量变量没有局部性或全局性,这取决于字典的全局性 如果要重命名变量名,则必须手动执行 然而,你要灵活得多,例如: 您可以决定覆盖现有变量或… ... 选择实现const变量 针对不同类型的重写引发异常 等。
也就是说,我已经实现了一个变量变量管理器类,它提供了上面的一些想法。它适用于python 2和3。
你可以这样使用这个类:
from variableVariablesManager import VariableVariablesManager
myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])
# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
print("not allowed")
except AttributeError as e:
pass
# rename a variable
myVars.renameVariable('myconst', 'myconstOther')
# preserve locality
def testLocalVar():
myVars = VariableVariablesManager()
myVars['test'] = 13
print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])
# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
myVars = VariableVariablesManager()
print("inside function myVars['globalVar']:", myVars['globalVar'])
myVars['globalVar'] = 13
print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])
如果你希望只允许覆盖相同类型的变量:
myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)
我回答的问题如何得到一个变量的值给定它的名字在一个字符串? 这是一个带有问题链接的副本。(编者注:它现在被关闭为“如何通过(字符串)名称选择变量?”的副本?)
如果所讨论的变量是对象的一部分(例如类的一部分),则可以使用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'