dis模块可以有效地用于将Python方法,函数和类反汇编为低级解释器指令。
我知道dis
信息可用于:
1.在使用线程的程序中查找竞争条件
2.找到可能的优化
根据您的经验,您是否知道反汇编Python功能可能有用的任何其他场景?
答案 0 :(得分:7)
dis
很有用,例如,当你有不同的代码做同样的事情,你想知道性能差异在哪里。
list += [item]
vs list.append(item)
def f(x): return 2*x
def f1(func, nums):
result = []
for item in nums:
result += [fun(item)]
return result
def f2(func, nums):
result = []
for item in nums:
result.append(fun(item))
return result
timeit.timeit
表示f2(f, range(100))
大约是f1(f, range(100)
的两倍。为什么呢?
(有趣的是f2
与map(f, range(100))
大致相同。)
您可以通过调用dis.dis(f1)
来查看dis的整个输出,这里是第4行。
4 19 LOAD_FAST 2 (result)
22 LOAD_FAST 1 (fun)
25 LOAD_FAST 3 (item)
28 CALL_FUNCTION 1
31 BUILD_LIST 1
34 INPLACE_ADD
35 STORE_FAST 2 (result)
38 JUMP_ABSOLUTE 13
>> 41 POP_BLOCK
同样,这里只有第4行:
4 19 LOAD_FAST 2 (result)
22 LOAD_ATTR 0 (append)
25 LOAD_FAST 1 (fun)
28 LOAD_FAST 3 (item)
31 CALL_FUNCTION 1
34 CALL_FUNCTION 1
37 POP_TOP
38 JUMP_ABSOLUTE 13
>> 41 POP_BLOCK
在f1
我们需要:
fun
(操作码28)item
result
(操作码34)result
(操作码35)在f2
中,我们只是:
fun
(操作码31)item
append
上致电result
(操作码34; C代码:快!)这解释了为什么(imho)更具表现力list += [value]
比list.append()
方法慢得多。
除此之外,dis.dis
主要用于好奇心以及尝试从.pyc
文件中重构代码而不花费大量资金来源:)
答案 1 :(得分:5)
我认为dis
模块本质上是一种学习工具。理解Python代码的某些片段的操作代码是开始让你对Python的掌握更加“深入” - 将对其语义的“抽象”理解植根于(更多)具体实现的样本中。有时,某些Python代码段行为的确切原因可能很难用“自上而下”来理解Python语义的“规则”中的纯粹推理:在这种情况下,通过一些“自下而上”验证来加强研究(基于可能的实施,当然 - 其他实施也是可能的;-)可以真正帮助研究的有效性。
答案 2 :(得分:3)
对于日常的Python编程,并不多。但是,如果您想了解为什么以某种方式做某事比其他方式更快,那么它很有用。我有时也用它来弄清楚完全解释器如何处理一些模糊的代码。但实际上,我很少提出一个实际的用例。
另一方面,如果你的目标是理解 python而不仅仅是能够在其中编程,那么它是一个非常宝贵的工具。例如,有没有想过函数定义是如何工作的?你走了:
>>> def f():
... def foo(x=[1, 2, 3]):
... y = [4,]
... return x + y
...
>>> dis(f)
2 0 LOAD_CONST 1 (1)
3 LOAD_CONST 2 (2)
6 LOAD_CONST 3 (3)
9 BUILD_LIST 3
12 LOAD_CONST 4 (<code object foo at 0xb7690770, file "<stdin>", line 2>)
15 MAKE_FUNCTION 1
18 STORE_FAST 0 (foo)
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
你可以看到这是通过将常量1,2和3推入堆栈,将堆栈中的内容放入列表,将其加载到代码对象中,将代码函数转换为对象并存储它来实现的。变成一个变量foo。