为什么我可以在Python for循环中为迭代器和序列使用相同的名称?

发布于 2021-01-29 15:07:36

这更多是一个概念上的问题。最近,我在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循环的两个部分中使用相同的变量名并具有它按预期起作用。它们在不同的范围内吗?允许这种事情发生的事情到底是怎么回事?

关注者
0
被浏览
57
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    什么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部分-我们从x24 LOAD_NAME 0 (x))中加载值,然后获得其迭代器(27 GET_ITER)并开始对其进行迭代(28 FOR_ITER)。Python 再也不会返回以再次加载迭代器

    旁白:
    这将没有任何意义的话,因为它已经拥有了迭代器,并作为作者Abhijit在他的回答指出Python的规范的第7.3实际上需要这种行为)。

    当名称x被覆盖以指向列表中以前称为xPython的每个值时,找到迭代器不会有任何问题,因为它无需x再次查看名称即可完成迭代协议。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看