- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直在使用 dis
模块来观察 CPython 字节码。但最近,我注意到 dis.dis()
的一些不便行为。
以这个例子为例:我首先定义了一个函数multiplier
,里面嵌套了一个函数inner
:
>>> def multiplier(n):
def inner(multiplicand):
return multiplicand * n
return inner
>>>
然后我使用 dis.dis()
反汇编它:
>>> from dis import dis
>>> dis(multiplier)
2 0 LOAD_CLOSURE 0 (n)
3 BUILD_TUPLE 1
6 LOAD_CONST 1 (<code object inner at 0x7ff6a31d84b0, file "<pyshell#12>", line 2>)
9 LOAD_CONST 2 ('multiplier.<locals>.inner')
12 MAKE_CLOSURE 0
15 STORE_FAST 1 (inner)
4 18 LOAD_FAST 1 (inner)
21 RETURN_VALUE
>>>
如您所见,它很好地反汇编了顶级代码对象。但是,它并没有反汇编inner
。它只是表明它创建了一个名为 inner
的代码对象,并显示了代码对象的默认(非信息性)__repr__()
。
有没有办法让 dis.dis()
递归打印代码对象?也就是说,如果我有嵌套的代码对象,它将打印出所有 代码对象的字节码,而不是在顶级代码对象处停止。我主要喜欢装饰器、闭包或生成器推导式等事物的此功能。
看来最新版本的 Python - 3.7 alpha 1 - 完全符合我想要的 dis.dis()
行为:
>>> def func(a):
def ifunc(b):
return b + 10
return ifunc
>>> dis(func)
2 0 LOAD_CONST 1 (<code object ifunc at 0x7f199855ac90, file "python", line 2>)
2 LOAD_CONST 2 ('func.<locals>.ifunc')
4 MAKE_FUNCTION 0
6 STORE_FAST 1 (ifunc)
4 8 LOAD_FAST 1 (ifunc)
10 RETURN_VALUE
Disassembly of <code object ifunc at 0x7f199855ac90, file "python", line 2>:
3 0 LOAD_FAST 0 (b)
2 LOAD_CONST 1 (10)
4 BINARY_ADD
6 RETURN_VALUE
What’s New In Python 3.7 文章记下了这一点:
The
dis()
function now is able to disassemble nested code objects (the code of comprehensions, generator expressions and nested functions, and the code used for building nested classes). (Contributed by Serhiy Storchaka in bpo-11822.)
但是,Python 3.7 还没有正式发布,如果你不想或不能使用 Python 3.7 怎么办?有没有办法在 Python 的早期版本(例如 3.5 或 2.7)中使用旧的 dis.dis()
来完成此操作?
最佳答案
你可以这样做(Python 3):
import dis
def recursive_dis(code):
print(code)
dis.dis(code)
for obj in code.co_consts:
if isinstance(obj, type(code)):
print()
recursive_dis(obj)
https://repl.it/@solly_ucko/Recursive-dis
请注意,您必须使用 f.__code__
而不是 f
来调用它。例如:
def multiplier(n):
def inner(multiplicand):
return multiplicand * n
return inner
recursive_dis(multiplier.__code__)
关于python - 有没有办法使 dis.dis() 递归打印代码对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44877745/
我是一名优秀的程序员,十分优秀!