usu*_* me 13 python bytecode disassembly python-internals
说我同意:
#!/usr/bin/env python
# encoding: utf-8
class A(object):
pass
Run Code Online (Sandbox Code Playgroud)
现在我拆开它:
python -m dis test0.py
4 0 LOAD_CONST 0 ('A')
3 LOAD_NAME 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 1 (<code object A at 0x1004ebb30, file "test0.py", line 4>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_NAME 1 (A)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
现在我在类定义中添加一些语句:
#!/usr/bin/env python
# encoding: utf-8
class A(object):
print 'hello'
1+1
pass
Run Code Online (Sandbox Code Playgroud)
然后我又拆开了:
4 0 LOAD_CONST 0 ('A')
3 LOAD_NAME 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 1 (<code object A at 0x1004ebb30, file "test0.py", line 4>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_NAME 1 (A)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
新语句中出现的新语句不是什么?
Mar*_*ers 17
新语句存储在嵌套字节码中.您可以在反汇编中看到加载了另一个代码对象:
9 LOAD_CONST 1 (<code object A at 0x1004ebb30, file "test0.py", line 4>)
Run Code Online (Sandbox Code Playgroud)
您需要检查该代码对象.这是因为类主体就像一个函数对象一样执行,然后调用产生的本地命名空间用于形成类成员.
演示:
>>> import dis
>>> def wrapper():
... class A(object):
... pass
...
>>> dis.dis(wrapper)
2 0 LOAD_CONST 1 ('A')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object A at 0x104b99930, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (A)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
>>> dis.dis(wrapper.__code__.co_consts[2])
2 0 LOAD_NAME 0 (__name__)
3 STORE_NAME 1 (__module__)
3 6 LOAD_LOCALS
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
这与您的第一个样本设置相同; 通过wrapper.__code__.co_consts元组访问类主体,这是LOAD_CONST字节代码所指的内容; 索引为2.
现在我们可以添加一个类体:
>>> def wrapper():
... class A(object):
... print 'hello'
... 1+1
... pass
...
>>> dis.dis(wrapper)
2 0 LOAD_CONST 1 ('A')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object A at 0x104b4adb0, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (A)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
>>> dis.dis(wrapper.__code__.co_consts[2])
2 0 LOAD_NAME 0 (__name__)
3 STORE_NAME 1 (__module__)
3 6 LOAD_CONST 0 ('hello')
9 PRINT_ITEM
10 PRINT_NEWLINE
4 11 LOAD_CONST 2 (2)
14 POP_TOP
5 15 LOAD_LOCALS
16 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
现在出现了班级的身体; 我们可以看到在加载类主体时将执行的字节代码.
值得注意的是为每个类体执行的字节码LOAD_NAME和STORE_NAME字节码; 那些检索模块名称并将它们存储为新的本地名称__module__,以便您的类__module__在创建后最终会得到一个属性.
然后LOAD_LOCALS字节码收集在这个'function'中产生的所有本地名称,并将其返回给调用者,这样BUILD_CLASS字节码就可以将它与'A'字符串一起使用,而object基元tuple(用其创建BUILD_TUPLE)可以产生新的类对象.
| 归档时间: |
|
| 查看次数: |
355 次 |
| 最近记录: |