传入字符串时,dis函数的作用是什么?

时间:2016-12-18 05:45:45

标签: python string python-2.7 bytecode

dis.dis()模块中的dis函数允许将原始字节码从代码对象反汇编为人类可读的形式。 dis()的文档说明了可以传递给函数的内容:

  

反汇编bytesource个对象。 bytesource 可以表示模块,类,方法,函数或代码对象。对于模块,它会反汇编所有功能。对于一个类,它会反汇编所有方法。对于单个代码序列,它每字节码指令打印一行。如果没有提供对象,它会反汇编最后一个回溯。

在试验模块时,一切都按预期工作。但是当我将一个str对象传递给函数并且运行正常时,我感到很惊讶:

>>> import dis
>>> dis.dis('1 + 2')
          0 <49>           
          1 SLICE+2        
          2 STORE_SLICE+3  
          3 SLICE+2        
          4 DELETE_SLICE+0 
>>> 

dis() 的文档具体表示允许传递给该函数的内容。我最后一次检查时,str不满足任何这些要求。 Per the documentation for code objects

  

代码对象表示字节编译的可执行Python代码或字节码。 [...]

但让我感到惊讶的是dis()生成的字节码。这个字节码是什么意思?我决定通过查看dis文档页面上的 32.12.1. Python Bytecode Instructions 来检查并查看每个操作码的含义。然而这让我更加困惑。有些操作码甚至没有记录(<49>)。

Python尝试使用我传入的字符串究竟是什么。是否考虑将我的字符串作为文字源代码?或者是试图从我传入的字符串构造一个字符串?

由于looking over the source code for dis.disassemble_string()dis.dis()传入str对象时>>> def func(): ... 1 + 2 ... >>> dis.dis(func) 2 0 LOAD_CONST 3 (3) 3 POP_TOP 4 LOAD_CONST 0 (None) 7 RETURN_VALUE >>> 调用的内容),我认为我以前的猜测是正确的。但如果这是真的,那么为什么字节码看起来如此奇怪?如果我传入一个具有相同表达式的函数,则字节码非常有意义:

>>> dis.dis('foo = 10')
          0 BUILD_TUPLE     28527
          3 SLICE+2        
          4 DELETE_SUBSCR  
          5 SLICE+2        
          6 <49>           
          7 <48>           
>>> dis.dis('print 0')
          0 JUMP_IF_TRUE_OR_POP 26994
          3 JUMP_FORWARD     8308 (to 8314)
          6 <48>           
>>> # etc...

但是,这种行为似乎并不局限于表达式。我尝试了其他几个语句,它们都生成了同样奇怪的字节码:

dis

这种行为是否记录在某处?我查看了ssh模块的整个文档页面,但我没有找到任何相关信息。

0 个答案:

没有答案