为什么我可以在Python for循环中为迭代器和序列使用相同的名称?
这更多是一个概念上的问题。最近,我在Python中看到了一段代码(它在2.7中有效,它也可能在2.5中运行过),其中一个for
循环对要迭代的列表和列表中的项目使用相同的名称,这既使我感到不道德,也使它不起作用。
例如:
x = [1,2,3,4,5]
for x in x:
print x
print x
产量:
1
2
3
4
5
5
现在,对我来说有意义的是,最后打印出的值将是循环中分配给x的最后一个值,但是我无法理解为什么您能够在for
循环的两个部分中使用相同的变量名并具有它按预期起作用。它们在不同的范围内吗?允许这种事情发生的事情到底是怎么回事?
-
什么
dis
告诉我们:Python 3.4.1 (default, May 19 2014, 13:10:29) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from dis import dis >>> dis("""x = [1,2,3,4,5] ... for x in x: ... print(x) ... print(x)""") 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 LOAD_CONST 2 (3) 9 LOAD_CONST 3 (4) 12 LOAD_CONST 4 (5) 15 BUILD_LIST 5 18 STORE_NAME 0 (x) 2 21 SETUP_LOOP 24 (to 48) 24 LOAD_NAME 0 (x) 27 GET_ITER >> 28 FOR_ITER 16 (to 47) 31 STORE_NAME 0 (x) 3 34 LOAD_NAME 1 (print) 37 LOAD_NAME 0 (x) 40 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 43 POP_TOP 44 JUMP_ABSOLUTE 28 >> 47 POP_BLOCK 4 >> 48 LOAD_NAME 1 (print) 51 LOAD_NAME 0 (x) 54 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 57 POP_TOP 58 LOAD_CONST 5 (None) 61 RETURN_VALUE
关键位是第2部分和第3部分-我们从
x
(24 LOAD_NAME 0 (x)
)中加载值,然后获得其迭代器(27 GET_ITER
)并开始对其进行迭代(28 FOR_ITER
)。Python 再也不会返回以再次加载迭代器 。旁白:
这将没有任何意义的话,因为它已经拥有了迭代器,并作为作者Abhijit在他的回答指出,Python的规范的第7.3实际上需要这种行为)。当名称
x
被覆盖以指向列表中以前称为x
Python的每个值时,找到迭代器不会有任何问题,因为它无需x
再次查看名称即可完成迭代协议。