3 python scope for-loop namespaces
我想知道是否有办法避免 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')
Run Code Online (Sandbox Code Playgroud)
印刷
[0, 1, 2, 3, 4]
1 i in global
4 j in for-loop
4 j in global
Run Code Online (Sandbox Code Playgroud)
编辑:
我假设 for 循环命名空间属于“全局”类别,与 LEGB 规则中的函数(“本地”)不同,因此可能没有解决方案?顺便说一句,Python 2.x 推导式没有自己的命名空间吗?因为评论中指出Python 2.x会打印“ 4 in global”(我使用的是Python 3.4)
forPython 中的循环没有自己的作用域;只有周围范围。因此,表达式中定义的任何变量都for将保留在该范围内。它们只是被添加到全局范围中,因为您在函数之外运行代码。如果将其添加到函数中,您会发现它不会“泄漏”:
def loop():
for j in range(5):
pass
>>> loop()
>>> 'j' in globals()
False
Run Code Online (Sandbox Code Playgroud)
在 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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1557 次 |
| 最近记录: |