避免将循环变量切入Python的方法';s全局命名空间

避免将循环变量切入Python的方法';s全局命名空间,python,for-loop,namespaces,scope,Python,For Loop,Namespaces,Scope,我想知道是否有一种方法可以避免将循环变量切入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,

我想知道是否有一种方法可以避免将循环变量切入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循环名称空间属于categoy“Global”,与LEGB规则中的函数(“Local”)不同,因此可能没有解决方案?顺便说一句,Python2.x理解是否没有自己的名称空间?由于评论中指出Python2.x将在global中打印“
4”(我使用的是Python3.4)

for
循环在Python中没有自己的作用域;只有周围的范围。因此,在
for
表达式中定义的任何变量都将保留在该范围内。它们只是被添加到全局范围中,因为您在函数之外运行代码。如果将其添加到函数中,您将看到它不会“泄漏”:

在Python2.x中,列表理解具有完全相同的行为:它们将迭代变量添加到局部范围中,因为它们基本上是
for
构造的语法糖。由于这似乎一直让人们感到惊讶,因此对Python3.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))

它在全局中为我显示
4i
。但我还是在用Python2x。有人知道为什么吗?哦,真的吗?我用的是Python3.4,真奇怪。这是我根据
print
语法假设的。这意味着for循环只有自己的名称空间,如果它们完成了,名称空间将被删除,但是如果同一个变量名已经在一个全局名称空间中定义,它将覆盖它?@SebastianRaschka根本没有
for
循环没有自己的名称空间,它们具有其存在范围的名称空间。在模块中,这是模块/全局级别。在函数中,这是本地级别的。
for
循环始终将其变量保留在现有范围中定义,并始终将任何现有变量重新绑定到其值。我在上面添加了一个例子来解释为什么这是有用的。arg,有一个愚蠢的副本和过去的错误,我忘了更改一个变量名。。。因此,关于for循环有自己的名称空间sry的误解现在已经清楚了。谢谢你的耐心;)
# 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))