我发现能够在运行时创建新变量并创建结果字典以便稍后处理(即写入文件)非常有用:
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()
返回一个包含局部变量(?)和
vars()[x] = y
创建[x:y]的新词典条目?
我有一个脚本,我在其中传递了使用{input1:data1,input2:data2}编写的字典,我使用此方法迭代所有值,存储所有结果,并将其输出到文件。这段代码在一个类中的函数内部,并且正在工作。
我的困惑之处在于我已经阅读了各种关于如何不与locals()混淆的帖子,以及vars()与locals()或者globals()等效(?)的方式。
所以我的问题(至少)是双重的:
1. vars()究竟是什么,特别是vars()[x] = y,
2.这本词典的范围是什么(在编写更大的程序时我需要记住的是
3.这是否是良好的编程习惯。
提前致谢!
答案 0 :(得分:35)
创建变量序列的pythonic方法
如果需要一系列变量,请创建一个序列。而不是尝试创建像:
这样的独立变量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开始,但它比它的价值更痛苦。我建议你习惯于拥有从零开始的列表。一切都围绕在他们周围,他们开始很快就感到自然。
vars()和locals()
现在,回答你问题的另一部分。 vars()
(或locals()
)提供对python创建的变量的低级访问。因此,以下两行是等效的。
locals()['x'] = 4
x = 4
vars()['x']
的范围与x
的范围完全相同。 locals()
(或vars()
)的一个问题是它会让你把东西放在命名空间中,而这些东西是你无法通过常规手段从命名空间中获取的。所以你可以做这样的事情:locals()[4] = 'An integer'
,但是如果不再使用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提供更简单,更不容易出错的方法(比如创建一系列变量),通常会遇到很多复杂问题。
答案 1 :(得分: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()
。只是停止使用它们并使用普通变量和普通字典。尽量避免你不理解的事情,并坚持使用简单明了的东西。
答案 2 :(得分:6)
来自vars的帮助,
VARS(...) vars([object]) - >字典
Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
你正在使用它没有vars,所以让我们看看本地人的帮助()
当地人(...) locals() - >字典
Update and return a dictionary containing the current scope's local
变量。
所以这先回答两个问题。 vars()将字典返回给局部变量,该变量由变量名称索引为字符串。范围是本地的。
我不确定第三个问题,但它确实看起来像一个不是一个好兆头的黑客。我想如果你只是在正确的范围内使用它,你就可以使用它。
答案 3 :(得分:5)
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
答案 4 :(得分:3)
我可以回答第3点:这不是很好的编程习惯。我并不确切地知道你想要完成什么,但我确信有一种更优雅的方式可以不使用locals()
(根据{{1}与vars()
相同)在交互式Python shell中。)
答案 5 :(得分:2)
以这种方式使用vars / locals或globals是(a)不良做法和(b)在所有情况下都不起作用。有关详细信息,请参阅Dynamically set local variable。底线:只使用dicts - 这就是他们的用途。