[原创]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部分。
  
  ---------------------------------------------------------------------










