利用dis模块分析python代码

作者信息:

Author : 黄志成(小黄)

博客地址: 博客

dis模块通过反汇编来支持CPython 字节码的分析.

下面通过一个例子来说明如何去分析python代码

a = [1, 2]
b = a
a = a + [3, 4]
print(a)
print(b)
a = [1, 2]
b = a
a += [3, 4]
print(a)
print(b)

第一个程序的结果是:

[1, 2, 3, 4]
[1, 2]

第二个程序的结果是:

[1, 2, 3, 4]
[1, 2, 3, 4]

同样是加法运算,但结果却大不同.这是为什么?

这个时候拿出我们的分析神器dis模块。

需要大家通过pip安装.

$ pip install dis

使用方法:

$ python3 -m dis demo1.py

命令行输入这行命令就能对这个文件的python代码进行分析.我们对这两段代码进行分析下

第一段代码分析结果:

  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 BUILD_LIST               2
              6 STORE_NAME               0 (a)

  2           8 LOAD_NAME                0 (a)
             10 STORE_NAME               1 (b)

  3          12 LOAD_NAME                0 (a)
             14 LOAD_CONST               2 (3)
             16 LOAD_CONST               3 (4)
             18 BUILD_LIST               2
             20 BINARY_ADD
             22 STORE_NAME               0 (a)

  4          24 LOAD_NAME                2 (print)
             26 LOAD_NAME                0 (a)
             28 CALL_FUNCTION            1
             30 POP_TOP

  5          32 LOAD_NAME                2 (print)
             34 LOAD_NAME                1 (b)
             36 CALL_FUNCTION            1
             38 POP_TOP
             40 LOAD_CONST               4 (None)
             42 RETURN_VALUE

第二段结果分析结果:

  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 BUILD_LIST               2
              6 STORE_NAME               0 (a)

  2           8 LOAD_NAME                0 (a)
             10 STORE_NAME               1 (b)

  3          12 LOAD_NAME                0 (a)
             14 LOAD_CONST               2 (3)
             16 LOAD_CONST               3 (4)
             18 BUILD_LIST               2
             20 INPLACE_ADD
             22 STORE_NAME               0 (a)

  4          24 LOAD_NAME                2 (print)
             26 LOAD_NAME                0 (a)
             28 CALL_FUNCTION            1
             30 POP_TOP

  5          32 LOAD_NAME                2 (print)
             34 LOAD_NAME                1 (b)
             36 CALL_FUNCTION            1
             38 POP_TOP
             40 LOAD_CONST               4 (None)
             42 RETURN_VALUE

dis分析后的结果 有三列分别是 行号 偏移量 指令 和 参数(目标对象)

我们主要看第三行.发现不同的地方

INPLACE_ADDBINARY_ADD.

这两个什么意思. 可以去官方手册中去查找 手册的地址:地址

官方手册中的说明:

BINARY_ADD Implements TOS = TOS1 + TOS.

INPLACE_ADD Implements in-place TOS = TOS1 + TOS.

这里有一个in-place的概念.那这个又是什么意思呢?继续看文档

In-place operations are like binary operations, in that they remove TOS and TOS1, and push the result back on the stack, but the operation is done in-place when TOS1 supports it, and the resulting TOS may be (but does not have to be) the original TOS1.

Binary operations remove the top of the stack (TOS) and the second top-most stack item (TOS1) from the stack. They perform the operation, and put the result back on the stack.

由于自己的水平问题,也没太理解这些意思.不过大致是说 INPLACE_ADD 这个操作是修改原数据,而非新建对象.BINARY_ADD会创建一个新对象。

为了验证这个结论,我们可以通过id函数来看看a,b变量的内存地址.

先对第一段程序进行分析.

a = [1, 2]
b = a
print('a:{0}\nb:{1}'.format(id(a),id(b)))
a += [3, 4]
print('a:{0}\nb:{1}'.format(id(a),id(b)))
print(a)
print(b)

结果是:

a:4339490312
b:4339490312
a:4339490312
b:4339490312
[1, 2, 3, 4]
[1, 2, 3, 4]

证明了那个观点.的确是修改原数据,而非创建一个新对象.我们在看看第二段程序

a = [1, 2]
b = a
print('a:{0}\nb:{1}'.format(id(a),id(b)))
a = a + [3, 4]
print('a:{0}\nb:{1}'.format(id(a),id(b)))
print(a)
print(b)

结果是:

a:4339600904
b:4339600904
a:4339673416
b:4339600904
[1, 2, 3, 4]
[1, 2]

果然是创建了一个新对象.结论正确.

dis模块是一个很强大的工具。对于我学习python的知识.很有帮助.

分析代码的方式不止命令行使用.也可以在代码中引用dis模块.然后使用dis.dis方法来分析代码.这里不过多介绍了。可以看文档了解.

这篇博客也就写这么多了。

学习之路漫长.本以为算是了解这些知识,但实际上还是有很多坑要爬.加油!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在学习和使用python的过程中,难免碰到一些不理解的地方,有时候还会因此踩到坑里许久爬不出来。这种情况下,一种解...
    light_cong阅读 2,861评论 0 4
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,907评论 0 38
  • 此刻,狂风大作,深夜冰凉。窗外风声肆虐,耳边响起雨水的滴答声。虽然未曾谋面,只是听闻声音,就感到来者不善,风加雨,...
    默小九Roxy阅读 314评论 0 0
  • 巧妇躬亲下灶厨,烹来美味宴归夫。 羹汤遍撒相思子,笑问冤家品到无?
    安若胡阅读 283评论 2 3
  • 2016年,贯穿全年的词汇是Struggle,Lust。因为欲望,因为贪婪,因为不甘心,所以不开心,是你应得的报应...
    Patrick_FJY阅读 575评论 0 0