有关Python2.x版本下的dis模块的使用

有关Python2.x版本下的dis模块的使用

事情源于昨天看书看到一个有意思的部分,就是在Python元组里面的元素如果存在可变的对象,比如Python里面的列表,类似下面这种形式:

t = (1, 2, [3, 4])

那么如果我执行t[2] += [5, 6]会发生什么,首先给我的感觉是这个会报错吧,这个是显而易见的,但是5能否添加进去呢?哈哈,突然觉得有点意思了,然后答案就是:

t变成(1, 2, [3, 4, 5, 6])
因为tuple不支持对它的赋值,所以会抛出TypeError异常

具体的报错信息可以在交互式环境中自行测试一下
  这个时候我们可以使用Python的dis模块来反编译一下,看看操作的字节码,如下所示:

In [14]: dis.dis(compile("t[2]+=[5, 6]", " ", "single"))
  1           0 LOAD_NAME                0 (t)
              3 LOAD_CONST               0 (2)
              6 DUP_TOPX                 2
              9 BINARY_SUBSCR
             10 LOAD_CONST               1 (5)
             13 LOAD_CONST               2 (6)
             16 BUILD_LIST               2
             19 INPLACE_ADD
             20 ROT_THREE
             21 STORE_SUBSCR
             22 LOAD_CONST               3 (None)
             25 RETURN_VALUE

因为我使用的是Python2的版本,所以在使用dis.dis的时候,我们需要先将代码编译一下,即使用compile方法,这里需要注意的是第三个参数,第三个参数有三个选项,"single"、"eval"、"exec",具体的可以help查看一下,下面我们来说一下上面字节码的关键行的解释:

BINARY_SUBSCR 表示将t[2]存入栈顶TOS
INPLACE_ADD 表示计算 TOS+[5, 6],这一步是可以完成的,因为TOS指向的是一个可变对象,也就是[3, 4]这个列表
STORE_SUBSCR 这一步失败,这是因为t是一个元组,是不可变的,对其元素进行赋值是不被允许的

所以我的建议是:

  • 不要把可变对象放入元组里面
  • 增量赋值不是一个原子操作,像上面的那样,虽然抛出错误,但是还是完成了操作
  • 了解Python代码背后的运行机制很有帮助
  • 不建议这样,虽然我们可以使用t[2].extend([5, 6])来完成操作,但是我们仍然不建议这样做,不要将可变对象放入元组中。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 179,907评论 25 708
  • 本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入...
    小小不懂11阅读 3,561评论 2 30
  • 愁绪不展眉头,自比东阳瘦,一盏孤檠凉月后。心之所向,旧乡世外繁华路。树下一杯憔悴,只求一醉。 秋风秋雨独自行,塞外...
    淮南以南阅读 266评论 2 4
  • 看到你的眼睛会笑 看到你的人会逃 静下,脑子里全是你的想到 不该这样的 一年的时间,会成为异地相思 很长,因有了思...
    西熙_b487阅读 175评论 0 0
  • html: jq: jq使用它的选择器,条件为option: selected,就能抓取到被选中的option. ...
    _信仰zmh阅读 2,011评论 0 0

友情链接更多精彩内容