Python:使用vars()将字符串赋值给变量

25 投票
7 回答
55618 浏览
提问于 2025-04-15 19:38

我发现能够在程序运行时创建新的变量,并把结果放进一个字典里以便后续处理,比如写入文件,这个功能非常有用:

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
    myDict[temp] = vars(temp)

这段代码会创建一个字典条目 [result1:data1],我可以通过 myDict[result1] 来调用它。我一直在使用 vars(),但其实并不太明白我在做什么。我猜 vars() 是返回一个包含本地变量的字典(对吗?),而

vars()[x] = y

是创建一个新的字典条目 [x:y] 吗?

我有一个脚本,传入一个准备好的字典 {input1:data1,input2:data2},然后我用这个方法遍历所有的值,存储所有的结果,并输出到一个文件里。这段代码是在一个类的函数内部,并且运行正常。

我感到困惑的是,我看到很多帖子说不应该随便动 locals(),而 vars() 和 locals() 是等价的(?),或者说 globals() 也是。

所以我的问题主要有两个方面:

1. vars(),特别是 vars()[x] = y 到底是干什么的,

2. 这个字典的作用范围是什么(在我写更大的程序时需要注意什么)

3. 这样做是否符合好的编程习惯。

提前谢谢你们!

7 个回答

6

根据关于vars的帮助信息,

vars(...)
vars([对象]) -> 字典

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

你在使用它的时候没有用到vars,所以我们来看看locals()的帮助信息。

locals(...)
locals() -> 字典

Update and return a dictionary containing the current scope's local

变量。

所以这就回答了你前两个问题。vars()会返回一个字典,里面包含了本地变量,字典的索引是变量名的字符串形式。它的作用范围是局部的。

我不太确定第三个问题,但这看起来有点像一种技巧,这可不是个好兆头。我想如果你小心使用它,只在正确的范围内使用,应该是可以的。

9

这样做吧。更简单。

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.

这就是你需要做的全部。

结果会是 myDict['variable1']myDict['variable9']

你很少需要用到 vars()locals()。干脆别用它们,直接用普通的变量和字典就行。尽量避免那些你不理解的东西,专注于简单明了的内容。

35

用Python的方式创建一系列变量

如果你想要一系列变量,最好的办法就是创建一个序列。不要试着去创建独立的变量,比如:

variable0
variable1
variable2
variable3

你应该考虑创建一个 list(列表)。这和S.Lott的建议很相似(S.Lott的建议通常都不错),而且在你的 for 循环中使用起来会更方便:

sequence = []
for _ in xrange(10):
    sequence.append(function_that_returns_data())

(注意我们丢掉了循环变量(_)。我们只是想要进行10次循环。)

这样你的数据就可以用以下方式访问:

sequence[0]
sequence[1]
sequence[2]
sequence[3]
[...]
sequence[9]

另外,你还可以这样做:

for datum in sequence:
    process_data(datum)

一开始,你可能会觉得序列从0开始有点不习惯。你可以尝试各种方法让你的数据从1开始,但这样做会比较麻烦。我建议你还是习惯使用从0开始的列表。因为所有东西都是围绕这个设计的,而且很快你就会觉得这样很自然。

vars() 和 locals()

现在,来回答你问题的另一部分。 vars()(或者 locals())可以让你低级访问Python创建的变量。因此,下面这两行是等价的。

locals()['x'] = 4
x = 4

vars()['x'] 的作用域和 x 是完全一样的。使用 locals()(或 vars())的一个问题是,它允许你在命名空间中放入一些东西,而你无法通过正常方式将其取出。所以你可以这样做: locals()[4] = '一个整数',但你不能在不再次使用 locals 的情况下取出这个值,因为局部命名空间(和所有Python命名空间一样)只应该存放字符串。

>>> x = 5
>>> dir()
['__builtins__', '__doc__', '__name__', 'x']
>>> locals()[4] = 'An integer'
>>> dir()
[4, '__builtins__', '__doc__', '__name__', 'x']
>>> x
5
>>> 4
4
>>> locals()[4]
'An integer'

注意,4 和 locals()[4] 返回的结果是不一样的。这可能会导致一些意想不到的、难以调试的问题。这也是为什么要避免使用 locals() 的原因之一。另一个原因是,使用它通常会让事情变得复杂,而Python提供了更简单、更不容易出错的方法来完成这些操作(比如创建一系列变量)。

撰写回答