利用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方法来分析代码.这里不过多介绍了。可以看文档了解.

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

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