我想知道是否有办法避免将for循环变量切入Python的全局命名空间?
到目前为止,我能想出的唯一解决方案是使用闭包,例如列表推导
,例如,以下代码:
i = 1
print([i for i in range(5)])
print(i, 'i in global')
j = 1
for j in range(5):
if j == 4:
print(j, 'j in for-loop')
print(j, 'j in global')
打印
[0, 1, 2, 3, 4]
1 i in global
4 j in for-loop
4 j in global
编辑:
我假设for循环命名空间属于类别“全局”,与LEGB规则中的函数(“Local”)不同,因此可能没有解决方案吗?顺便说一句,Python 2.x的理解是不是有自己的命名空间?因为在评论中指出Python 2.x会打印“4 in global
”(我使用的是Python 3.4)
答案 0 :(得分:3)
for
循环在Python中没有自己的范围;只有周围的范围。因此for
表达式中定义的任何变量都将保留在该范围内。它们只是被添加到全局范围内,因为您在函数之外运行代码。如果您将其添加到某个功能中,您会发现它没有"泄漏":
def loop():
for j in range(5):
pass
>>> loop()
>>> 'j' in globals()
False
在Python 2.x中,列表推导具有完全相同的行为:它们会将迭代变量添加到局部范围中,因为它们基本上是for
构造的语法糖。由于这似乎不断给人们带来惊喜,因此对Python 3.x进行了更改,以便将变量添加到本地范围。
另请注意,列表推导具有不同的语义:它们更接近于list()构造函数中的生成器表达式的语法糖,特别是循环控制变量不再泄漏到周围的范围中。
for
循环的范围行为对于以下模式非常有用:
# find line number in file with matching text
for i, line in enumerate(some_file):
if 'some text' in line:
break
print('First match found at line {}.'.format(i))