为什么 Python 在反汇编字节码中使用“.0”表示迭代器?
Why does Python use ".0" to represent an iterator in disassembled byte code?
考虑这个例子
>>> dis.dis("[1 for i in range(3)]")
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x10d6045d0, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_NAME 0 (range)
8 LOAD_CONST 2 (3)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x10d6045d0, file "<dis>", line 1>:
1 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0) <------ Look at this
>> 4 FOR_ITER 8 (to 14)
6 STORE_FAST 1 (i)
8 LOAD_CONST 0 (1)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 4
>> 14 RETURN_VALUE
反汇编的字节码中有一个奇怪的.0
。
通过分析每条指令,我知道它代表一个迭代器iter(range(3))
,但为什么Python不使用像iter(range(3))
这样更直观的表示,因为它已经知道它的值?
这是一个变量名。为列表理解生成的函数采用单个参数,该参数被赋予通常禁止的名称 .0
以确保该名称不会与任何常规变量冲突。如果 Python 必须生成更多名称,他们会去 .1
、.2
等
dis
输出显示 .0
,因为 LOAD_FAST
指令是从 .0
变量读取的。 dis
不会去寻找变量值来自的表达式;这将是很多额外的工作,一般来说是不可能的,而且对于它正在反汇编的字节码来说也不那么真实。
考虑这个例子
>>> dis.dis("[1 for i in range(3)]")
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x10d6045d0, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_NAME 0 (range)
8 LOAD_CONST 2 (3)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x10d6045d0, file "<dis>", line 1>:
1 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0) <------ Look at this
>> 4 FOR_ITER 8 (to 14)
6 STORE_FAST 1 (i)
8 LOAD_CONST 0 (1)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 4
>> 14 RETURN_VALUE
反汇编的字节码中有一个奇怪的.0
。
通过分析每条指令,我知道它代表一个迭代器iter(range(3))
,但为什么Python不使用像iter(range(3))
这样更直观的表示,因为它已经知道它的值?
这是一个变量名。为列表理解生成的函数采用单个参数,该参数被赋予通常禁止的名称 .0
以确保该名称不会与任何常规变量冲突。如果 Python 必须生成更多名称,他们会去 .1
、.2
等
dis
输出显示 .0
,因为 LOAD_FAST
指令是从 .0
变量读取的。 dis
不会去寻找变量值来自的表达式;这将是很多额外的工作,一般来说是不可能的,而且对于它正在反汇编的字节码来说也不那么真实。