python 源码解读2
http://www.jianshu.com/users/4d4a2f26740b/latest_articles
http://blog.csdn.net/ssjhust123/article/category/3202957
http://tech.uc.cn/?p=1932
>>>src=open("./test.py").read() >>>co=compile(src,"test.py","exec") >>>dir(co) >>> dir(co) ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames'] >>> print co.co_names ('a', 'b', 'c', 'd', 'object', 'Student', 'func', 'bart', 'name', 'score') >>> print co.co_consts ('hello', 1, 1.0, '100', 'Student', <code object Student at 0x7f1d2b7a2918, file "test.py", line 5>, <code object func at 0x7f1d2b7a25d0, file "test.py", line 9>, 'this is name', 'this is score', None) >>> co.co_code 'd\x00\x00Z\x00\x00d\x01\x00Z\x01\x00d\x02\x00Z\x02\x00d\x03\x00Z\x03\x00d\ x04\x00e\x04\x00f\x01\x00d\x05\x00\x84\x00\x00\x83\x00\x00YZ\x05\x00d\x06\x00\ x84\x00\x00Z\x06\x00e\x06\x00\x83\x00\x00\x01e\x05\x00d\x07\x00d\x08\x00\x83\ x02\x00Z\x07\x00e\x07\x00i\x08\x00GHe\x07\x00i\t\x00GHd\t\x00S' >>> import dis >>> print dis.dis(co) 1 0 LOAD_CONST 0 ('hello') 3 STORE_NAME 0 (a) 2 6 LOAD_CONST 1 (1) 9 STORE_NAME 1 (b) 3 12 LOAD_CONST 2 (1.0) 15 STORE_NAME 2 (c) 4 18 LOAD_CONST 3 ('100') 21 STORE_NAME 3 (d) 5 24 LOAD_CONST 4 ('Student') 27 LOAD_NAME 4 (object) 30 BUILD_TUPLE 1 33 LOAD_CONST 5 (<code object Student at 0x7f1d2b7a2918, file "test.py", line 5>) 36 MAKE_FUNCTION 0 39 CALL_FUNCTION 0 42 BUILD_CLASS 43 STORE_NAME 5 (Student) 9 46 LOAD_CONST 6 (<code object func at 0x7f1d2b7a25d0, file "test.py", line 9>) 49 MAKE_FUNCTION 0 52 STORE_NAME 6 (func) 11 55 LOAD_NAME 6 (func) 58 CALL_FUNCTION 0 61 POP_TOP 12 62 LOAD_NAME 5 (Student) 65 LOAD_CONST 7 ('this is name') 68 LOAD_CONST 8 ('this is score') 71 CALL_FUNCTION 2 74 STORE_NAME 7 (bart) 13 77 LOAD_NAME 7 (bart) 80 LOAD_ATTR 8 (name) 83 PRINT_ITEM 84 PRINT_NEWLINE 14 85 LOAD_NAME 7 (bart) 88 LOAD_ATTR 9 (score) 91 PRINT_ITEM 92 PRINT_NEWLINE 93 LOAD_CONST 9 (None) 96 RETURN_VALUE None ----------------------------------------------------------- typedef struct _frame { PyObject_VAR_HEAD struct _frame *f_back; /* 调用者的帧 */ PyCodeObject *f_code; /* 帧对应的字节码对象 */ PyObject *f_builtins; /* 内置名字空间 */ PyObject *f_globals; /* 全局名字空间 */ PyObject *f_locals; /* 本地名字空间 */ PyObject **f_valuestack; /* 运行时栈底 */ PyObject **f_stacktop; /* 运行时栈顶 */ ……. } typedef struct { PyObject_HEAD int co_argcount; /* 位置参数个数 */ int co_nlocals; /* 局部变量个数 */ int co_stacksize; /* 栈大小 */ int co_flags; PyObject *co_code; /* 字节码指令序列 */ PyObject *co_consts; /* 所有常量集合 */ PyObject *co_names; /* 所有符号名称集合 */ PyObject *co_varnames; /* 局部变量名称集合 */ PyObject *co_freevars; /* 闭包用的的变量名集合 */ PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */ /* The rest doesn’t count for hash/cmp */ PyObject *co_filename; /* 代码所在文件名 */ PyObject *co_name; /* 模块名|函数名|类名 */ int co_firstlineno; /* 代码块在文件中的起始行号 */ PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */ void *co_zombieframe; /* for optimization only (see frameobject.c) */ } PyCodeObject; ----------------------------------------------------------------------- [root@monitor ~]# vi test.py a="hello" b=1 c=1.0 d='100' class Student(object): def __init__(self, name, score): self.name = name self.score = score def func(): a="hello" b=1 c=1.0 d='100' class Student(object): def __init__(self, name, score): self.name = name self.score = score def func(): import sys frame = sys._getframe() print frame.f_locals print frame.f_globals print frame.f_back.f_locals print a func() [root@monitor ~]# python test.py { 'sys': <module 'sys' (built-in)>, 'frame': <frame object at 0x1569750> } {'a': 'hello', 'c': 1.0, 'b': 1, 'func': <function func at 0x7facf5cbbc08>, 'd': '100', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, 'Student': <class '__main__.Student'>, '__name__': '__main__', '__doc__': None } {'a': 'hello', 'c': 1.0, 'b': 1, 'func': <function func at 0x7facf5cbbc08>, 'd': '100', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, 'Student': <class '__main__.Student'>, '__name__': '__main__', '__doc__': None } hello this is name this is score ------------------------------------------------------------------------ a="hello" def func(): import sys frame = sys._getframe() print frame.f_locals print frame.f_globals print frame.f_back.f_locals print a "test.py" 12L, 165C written
[root@monitor ~]# python test.py
{ 'sys': <module 'sys' (built-in)>,
'frame': <frame object at 0xb67d30>}
{ 'a': 'hello',
'__builtins__': <module '__builtin__' (built-in)>,
'__file__': 'test.py',
'__package__': None,
'func': <function func at 0x7fc658a87938>,
'__name__': '__main__',
'__doc__': None}
{ 'a': 'hello',
'__builtins__': <module '__builtin__' (built-in)>,
'__file__': 'test.py',
'__package__': None,
'func': <function func at 0x7fc658a87938>,
'__name__': '__main__',
'__doc__': None}
hello
----------------------------------------------------------- >>> src=open("./test.py").read() >>> co=compile(src,"test.py","exec") >>> co.co_consts ('hello', <code object func at 0x7f1f75deb558, file "test.py", line 4>, None) >>> import dis >>> dis.dis(co.co_consts[1]) 5 0 LOAD_CONST 1 (-1) 3 LOAD_CONST 0 (None) 6 IMPORT_NAME 0 (sys) 9 STORE_FAST 0 (sys) 6 12 LOAD_FAST 0 (sys) 15 LOAD_ATTR 1 (_getframe) 18 CALL_FUNCTION 0 21 STORE_FAST 1 (frame) 7 24 LOAD_FAST 1 (frame) 27 LOAD_ATTR 2 (f_locals) 30 PRINT_ITEM 31 PRINT_NEWLINE 8 32 LOAD_FAST 1 (frame) 35 LOAD_ATTR 3 (f_globals) 38 PRINT_ITEM 39 PRINT_NEWLINE 9 40 LOAD_FAST 1 (frame) 43 LOAD_ATTR 4 (f_back) 46 LOAD_ATTR 2 (f_locals) 49 PRINT_ITEM 50 PRINT_NEWLINE 10 51 LOAD_GLOBAL 5 (a) 54 PRINT_ITEM 55 PRINT_NEWLINE 56 LOAD_CONST 0 (None) >>> print co.co_names ('a', 'func') >>> print co.co_consts ('hello', <code object func at 0x7f1f75deb558, file "test.py", line 4>, None) 第一列表示以下几个指令在py文件中的行号; 第二列是该指令在指令序列co_code里的偏移量; 第三列是指令opcode的名称,分为有操作数和无操作数两种,opcode在指令序列中是一个字节的整数; 第四列是操作数oparg,在指令序列中占两个字节,基本都是co_consts或者co_names的下标; 第五列带括号的是操作数说明。