两行Python代码产生3个执行块

两行Python代码产生3个执行块,python,python-3.x,python-3.7,Python,Python 3.x,Python 3.7,我正在试验Python操作码,看到下面的dis.dis的输出,我感到惊讶。给出了以下两行: [i for i in range(10)] print("OK") 如您所见,这两条线形成3个块。为什么第一和第三街区属于第一条线?这也是按这个顺序执行的吗?我希望从C或C++编译器中得到这样的无序指令,但我不理解第三个块: 1 0 LOAD_CONST 0 (<code object <listcomp> at 0x109664540

我正在试验Python操作码,看到下面的
dis.dis
的输出,我感到惊讶。给出了以下两行:

[i for i in range(10)]
print("OK")
如您所见,这两条线形成3个块。为什么第一和第三街区属于第一条线?这也是按这个顺序执行的吗?我希望从
C
C++
编译器中得到这样的无序指令,但我不理解第三个块:

1           0 LOAD_CONST               0 (<code object <listcomp> at 0x109664540, file "example.py", line 1>)
            2 LOAD_CONST               1 ('<listcomp>')
            4 MAKE_FUNCTION            0
            6 LOAD_NAME                0 (range)
            8 LOAD_CONST               2 (10)
            10 CALL_FUNCTION            1
            12 GET_ITER
            14 CALL_FUNCTION            1
            16 POP_TOP

2          18 LOAD_NAME                1 (print)
            20 LOAD_CONST               3 ('OK')
            22 CALL_FUNCTION            1
            24 POP_TOP
            26 LOAD_CONST               4 (None)
            28 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x109664540, file "test", line 1>:
1           0 BUILD_LIST               0
            2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                 8 (to 14)
            6 STORE_FAST               1 (i)
            8 LOAD_FAST                1 (i)
            10 LIST_APPEND              2
            12 JUMP_ABSOLUTE            4
        >>   14 RETURN_VALUE
10加载常量0()
2荷载常数1(“”)
4生成函数0
6加载单元名称0(范围)
8负载常数2(10)
10调用函数1
12获取ITER
14调用函数1
16件流行上衣
2 18加载单元名称1(打印)
20负载常数3(“正常”)
22调用函数1
24件流行上衣
26负载常数4(无)
28返回值
反汇编位于0x109664540的:
1 0生成\u列表0
2加载速度为0(.0)
>>国际热核实验堆8(至14)4
6商店快速1(i)
8加载速度1(i)
10清单2
12跳/绝对4
>>14返回值
什么是
>
? 文档将它们描述为
带标签的指令,用>>,
表示,但我不能将此注释应用于上面的示例。

解释器在删除列表时创建的
是一个单独的对象。它用于隔离理解名称空间(循环变量
i
)并构建列表。它首先被创建,然后经过一些准备后被调用,最后被丢弃


您可以在开始处看到正在创建的辅助对象:

1           0 LOAD_CONST               0 (<code object <listcomp> at 0x109664540, file "example.py", line 1>)
            2 LOAD_CONST               1 ('<listcomp>')
            4 MAKE_FUNCTION            0
这将加载range函数及其参数,然后应用它——我们现在在堆栈顶部有
range(10)
。最后,删除范围并用其迭代器替换它

最后,Python调用helper函数:

        14 CALL_FUNCTION            1
请记住,我们的堆栈以前是用helper函数
和范围迭代器填充的。其他一切都从堆栈中消失了。因此,Python在这里使用范围迭代器作为参数调用helper函数。帮助器返回列表理解产生的列表


  • 什么是
    >
它们是字节码执行中可能的跳跃/分支的可视化

例如,可以执行
For
循环(跳到循环的末尾),也可以执行另一项(跳到循环的开头)。您可以在反汇编中看到这一点:

  >>    4 FOR_ITER                 8 (to 14)
        6 STORE_FAST               1 (i)
        8 LOAD_FAST                1 (i)
        10 LIST_APPEND              2
        12 JUMP_ABSOLUTE            4
   >>   14 RETURN_VALUE
指令4是循环的迭代(即在列表中)。它的参数(右边)是块大小,即8。这意味着完成后,它将跳到14,返回指令标记为
>
。由于循环必须对每个项目重复,因此它的最后一条指令12是跳转到4处的循环指令-也用
>
标记

  >>    4 FOR_ITER                 8 (to 14)
        6 STORE_FAST               1 (i)
        8 LOAD_FAST                1 (i)
        10 LIST_APPEND              2
        12 JUMP_ABSOLUTE            4
   >>   14 RETURN_VALUE