[原创]python字节码(bytecode与opcode)(一)...
时间:2010-08-15 来源:akara
[原创]Python字节码(bytecode与opcode)(一)
by AKara 2007-01-31 @ http://blog.csdn.net/akara @ [email protected]
---------------------------------------------------------------------
本系列文章针对Python2.5 final的bytecode/opcode做一些摘要和分析。
温故知新。
by AKara 2007-01-31 @ http://blog.csdn.net/akara @ [email protected]
转载请保留作者信息。谢谢。
---------------------------------------------------------------------
什么是bytecode
---------------------------------------------------------------------
Python脚本"compile"后生成的.pyc(.pyo)即是bytecode。
举一个最简单的例子,假设一个codetest.py只包含一行语句:
import sys
那它对应的codetest.pyc文件的所有bytecode内容用十六进制解释如下图:
---------------------------------------------------------------------
bytecode layout
---------------------------------------------------------------------
这里解释一下上图的bytecode内容代表的意思。
图中红色的字符为对象标志符,标志一个新对象的开始。
Python处理bytecode时将根据标志符来读入相应类型的对象。
/Python/marshal.c中定义了所有的对象标志符:
#define TYPE_NULL '0'
#define TYPE_NONE 'N'
#define TYPE_FALSE 'F'
#define TYPE_TRUE 'T'
#define TYPE_STOPITER 'S'
#define TYPE_ELLIPSIS '.'
#define TYPE_INT 'i'
#define TYPE_INT64 'I'
#define TYPE_FLOAT 'f'
#define TYPE_BINARY_FLOAT 'g'
#define TYPE_COMPLEX 'x'
#define TYPE_BINARY_COMPLEX 'y'
#define TYPE_LONG 'l'
#define TYPE_STRING 's'
#define TYPE_INTERNED 't'
#define TYPE_STRINGREF 'R'
#define TYPE_TUPLE '('
#define TYPE_LIST '['
#define TYPE_DICT '{'
#define TYPE_CODE 'c'
#define TYPE_UNICODE 'u'
#define TYPE_UNKNOWN '?'
#define TYPE_SET '<'
#define TYPE_FROZENSET '>'
现在,将上图中出现过的对象标志符先后排列后分析如下:
(1) 'c'——TYPE_CODE:表示接下来存放的是一个code object。
BTW:
本例的pyc中,其实以下(2)到(13)的对象标志符都是在描述一个
code object时遇到的子对象标志符。即是描述了一个code object。
(2)'s'——TYPE_STRING;表示接下来存放的是一个string object。
(3)'('——TYPE_TUPLE;表示接下来存放的是一个tuple object。
(4)'i'——TYPE_INT;表示接下来存放的是一个integer object。
(5)'N'——TYPE_NONE;表示Py_None。它是一个单件,无需后续描述。
(6)'('——TYPE_TUPLE;表示接下来存放的是一个tuple object。
(7)'t'——TYPE_INTERNED;表示接下来存放的是一个interned string。
BTW:
Intern是Python的字符串对象复用机制。
如某字符串进行了intern,则后续再遇到的同样字符串将直接复用对象。
(其实新对象还是会构造,只不过立刻就因为refcount为0而纳入gc)
Interned的好处是:
> 节省存储:所有interned string对象均唯一。
> 提高性能:比较interned string对象相等时只需要比较指针是否相等;
Python2.5在module,class,attribute等名称上都用interned string。
脚本也提供了intern(string)函数来强制一个字符串对象成为interned。
(8)'('——TYPE_TUPLE;表示接下来存放的是一个tuple object。
(9)'('——TYPE_TUPLE;表示接下来存放的是一个tuple object。
(10)'('——TYPE_TUPLE;表示接下来存放的是一个tuple object。
(11)'s'——TYPE_STRING;表示接下来存放的是一个string object。
(12)'s'——TYPE_STRING;表示接下来存放的是一个string object。
(13)'s'——TYPE_STRING;表示接下来存放的是一个string object。
---------------------------------------------------------------------
本例的codetest.pyc非常简单和特殊,但足够用来说明bytecode的概要结构。
更详细的bytecode结构分析并不在本系列文章的内容范围,相关读/写/处理可参考
/Python/ast.c, /Python/compile.c, /Python/marshal.c, /Python/ceval.c等。
---------------------------------------------------------------------
简单的bytecode说明后。下篇将转入bytecode中最重要的opcode部分。
---------------------------------------------------------------------