Python: Using vars() to assign a string to a variable
我发现能够在运行时创建新的变量,并创建结果的字典以便以后处理非常有用,例如,写入文件:
1 2 3 4 5 | 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()[x] = y
是否创建[X:Y]的新字典条目?
我有一个脚本,我在其中传递一个用input1:data1,input2:data2编写的字典,我使用这个方法迭代所有值,存储所有结果,并将其输出到一个文件。这个代码位在一个类中的一个函数内,并且正在工作。
我的困惑源于我读了很多关于locals()不应该被弄乱的文章,以及vars()是如何等价的(?)到locals()或globals()。
所以我的问题是(至少)双重的:
1.vars()具体做什么,特别是vars()[x]=y做什么,
2.这本字典的范围是什么(当我写更大的程序时,我需要记住的是什么)
3.这是否是良好的编程实践。
事先谢谢!
创建变量序列的方法
如果需要变量序列,请创建一个序列。而不是试图创建独立变量,如:
1 2 3 4 | variable0 variable1 variable2 variable3 |
您应该考虑创建一个
1 2 3 | sequence = [] for _ in xrange(10): sequence.append(function_that_returns_data()) |
(注意,我们丢弃了循环变量(
然后您的数据将可用为:
1 2 3 4 5 6 | sequence[0] sequence[1] sequence[2] sequence[3] [...] sequence[9] |
作为额外的奖励,您可以:
1 2 | for datum in sequence: process_data(datum) |
一开始,你可能会因为你的序列从0开始而抽搐。你可以通过各种扭曲让你的实际数据从1开始,但这比它的价值更痛苦。我建议您习惯使用零基列表。一切都是围绕着它们建造的,它们很快就开始感觉自然了。
vars()和locals()。
现在,回答你问题的另一部分。
1 2 | locals()['x'] = 4 x = 4 |
1 2 3 4 5 6 7 8 9 10 11 12 | >>> 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]相同的内容。这可能会导致一些意外的、难以调试的问题。这是避免使用
改为这样做。这更简单。
1 2 3 4 | myDict = {} for i in range (1,10): temp ="variable"+str(i) myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc. |
这就是你所需要做的。
结果将是
你很少需要
在Vars的帮助下,
vars(...)
vars([object]) -> dictionary
1
2 Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
您使用它时没有var,所以让我们看看本地人的帮助()。
locals(...)
locals() -> dictionary
1 Update and return a dictionary containing the current scope's localvariables.
所以这就回答了前两个问题。vars()将字典返回到以变量名称作为字符串索引的局部变量。范围是本地的。
我不确定第三个问题,但它看起来确实有点像黑客,这不是一个好迹象。我想如果你小心地只在正确的范围内使用它,你就可以通过它。
jcdyer很好地解释了这些概念,justin peel清楚地说明了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Bull(object): def __init__(self): self.x = 1 self.y ="this" def __repr__(self): return"Bull()" def test1(self): z = 5 return vars() def test2(self): y ="that" return vars(self) def test3(self): return locals() def test4(self): y = 1 return locals() if __name__ =="__main__": b = Bull() print b.test1() print b.test2() print b.test3() print b.test4() print vars(b).get("y") |
结果是:
1 2 3 4 5 | {'self': Bull(), 'z': 5} {'y': 'this', 'x': 1} {'self': Bull()} {'y': 1, 'self': Bull()} this |
我可以回答第3个问题:这不是很好的编程实践。我不太清楚您想要完成什么,但我确信有一种更优雅的方法可以不用使用
以这种方式使用vars/locals或globals是(a)糟糕的做法,(b)并非在所有情况下都有效。有关详细信息,请参阅动态设置局部变量。底线:只要用听写——这就是他们的目的。