gpt4 book ai didi

python - 有没有办法使 dis.dis() 递归打印代码对象?

转载 作者:太空狗 更新时间:2023-10-30 01:26:32 25 4
gpt4 key购买 nike

我一直在使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com