2010-02-23 61 views
20

我发现它非常有用,能够在运行时创建新的变量和创造的结果进行处理的字典后,即写入文件:的Python:使用瓦尔()将一个字符串分配给一个变量

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

它创建了我可以用myDict [result1]调用的字典条目[result1:data1]。我一直在使用vars()而没有真正理解我在做什么。我把它vars()返回与局部变量的字典,并

瓦尔()[X] = Y

创建[X:Y]的新字典项(?)?

我有一个脚本,我在{input1:data1,input2:data2}准备的字典中传递,我使用此方法遍历所有值,存储所有结果并将其输出到文件。这段代码是在一个类中的函数中,并且正在工作。

我的困惑的根源是,我已经阅读了如何当地人各个岗位()不应该与被搞砸了,怎么瓦尔()相当于(?)当地人(),或全局()..

所以我的问题是(至少)两个方面:

1.什么究竟VARS(),或特别是,乏()[X] = Y这样做,

2.什么范围这个字典是(我需要记住我写大程序

3.Whether这是良好的编程 实践。

在此先感谢!

回答

32

的Python的方式来创建变量

序列如果你想要的变量序列,创建一个序列。而不是试图建立独立的变量,例如:

variable0 
variable1 
variable2 
variable3 

你应该看看创建list。这类似于美国洛特是在暗示(美国洛特通常有很好的建议),但地图更加整齐到你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开始,但它比它的价值更痛苦。我建议仅仅习惯于从零开始的列表。一切都围绕在他们周围,他们开始感觉自然很快。

瓦尔()和locals()

现在回答你的问题的另一部分。 vars()(或locals())提供对由python创建的变量的低级访问。因此以下两行是等同的。

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

vars()['x']范围是完全一样的x范围。 locals()(或vars())的一个问题是,它可以让你把东西放在名字空间中,通过一般的方式你不能离开名字空间。所以你可以做这样的事情:locals()[4] = 'An integer',但是如果不再使用局部变量,你将无法恢复原状,因为局部命名空间(和所有的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提供的更简单,不易出错的方法(比如创建一系列变量),通常会遇到很多复杂的事情。

+2

我认为'vars()['x'] = 4'和'x = 4'实际上只相当于一些时间。如果你在一个函数中这样做,并且不在其他地方设置'x',并且函数被编译器优化了,那么函数后面的'x'的正常查找(即'y = x + 2')没有工作。我认为编译器会缓存它可以看到的变量(可能在编译时定义),并没有考虑到这种shenanigan。如果你为你的函数添加一个exec语句,那么编译器不会尝试优化函数。 – 2010-02-23 21:05:10

+1

感谢周到的答案, 在序列数据: 功能(基准) 看起来非常有用的。今天我学到了很多东西,谢谢! – PPTim 2010-02-23 21:28:38

+0

要查找关于该构造的更多信息,请查找“python迭代器” – jcdyer 2010-02-23 22:04:09

2

我可以回答3号:这不是很好的编程习惯。我完全不看你想实现什么,但我相信有这样做不使用locals()(这是一样的vars()根据在交互式Python外壳help(vars))的更优雅的方式。

5

从帮助增值经销商,

瓦尔(...) 瓦尔([对象]) - >词典

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

你正在使用它没有增值经销商,让我们看看帮助当地人()

当地人(...) 当地人() - >词典

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

变量。

所以这个回答你的前两个问题。 vars()将一个字典返回给由变量名称索引的局部变量作为字符串。范围是本地的。

我不知道关于第三个问题,但它似乎是一种黑客攻击这是不是一个好兆头的。我想如果你只是在正确的范围内使用它,你可以随心所欲地使用它。

+0

我在我的困惑我忘了寻求帮助(),所以赶上了。谢谢, – PPTim 2010-02-23 21:20:59

6

取而代之。这很简单。

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()。只要停止使用它们并使用普通变量和普通字典即可。尽量避免你不理解的东西,坚持简单明了的东西。

+0

现在我想到了为什么我使用了vars(),这可能是因为在我逐行测试代码时能够立即调用变量的感觉很好。感谢你的回答! – PPTim 2010-02-23 21:20:00

1

以这种方式使用变量/本地变量或全局变量是(a)不好的练习和(b)在所有情况下都不起作用。有关更多详细信息,请参阅Dynamically set local variable。底线:只需使用字典 - 这就是他们的目的。

4

jcdyer非常好地解释了这些概念,Justin Peel明确指出了vars()locals()的作用。但是一个小例子总能加速理解。

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") 

导致:

{'self': Bull(), 'z': 5} 
{'y': 'this', 'x': 1} 
{'self': Bull()} 
{'y': 1, 'self': Bull()} 
this 
相关问题