- reference: Python 源码剖析
- Python_virtual_machine
- Python虚拟机的执行环境
- 名字、作用域和名字空间
- Python虚拟机的运行框架
- Python运行时环境初探
1.Python虚拟机框架
a.Python虚拟机的执行环境
PyCodeObject对象没有包含也不可能包含程序运行的动态信息–执行环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| [frameobject.h] 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; .... int f_lasti; int f_lineno;
....
PyObject* f_localsplus[1]; } PyFrameObject;
|
python运行时栈指运算时所需要的内存空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [frameobject.c] PyFrameObject* PyFrame_New(PyThreadState* tstate, PyCodeObject* code, PyObject* globals, PyObject* locals){ PyFrameObject* f; Py_ssize_t extras,ncells,nfrees,i; ncells = PyTuple_GET_SIZE(code->co_cellvars); nfrees = PyTuple_GET_SIZE(code->co_freevars); extras = code->co_stacksize + code->co_nlocals + ncells + nfrees; f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type,extras); extras = code->co_nlocals + ncells + nfrees; f->f_valuestack = f->f_localsplus + extras; f->f_stacktop = f->f_valuestack; return f; }
|
b.名字、作用域和名字空间
module:1.代码复用 2.划分名字空间
module加载方法:1.import动态加载 2.主module加载
(name,obj)关联关系称为约束, 约束的容身之处就是名字空间
属性引用是另一个名字空间中的名字,是一个访问对象属性的动作
Python具有静态作用域,因为约束在文本中的位置不是在运行时动态决定的
Python支持嵌套作用域
名字引用动作沿着local作用域、global作用域、builtin作用域的顺序查找名字对应的约束
1 2 3 4 5 6 7 8 9 10
| a = 1 def f(): a = 2 def g(): print a return g
func = f( func() )
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| //错误案例
a = 1
def g(): print a
def f(): print a a = 2 print a
g() f()
>> "local variable 'a' referenced before assignment"
|
c.Python虚拟机的运行框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| [ceval.c]
PyObject* PyEval_EvalFrameEx(PyFrameObject* f,int throwflag){ ... why = WHY_NOT; ... for(;;){ .... fast_next_opcode: f->f_lasti = INSTR_OFFSET(); opcode = NEXTOP(); oparg = 0; if(HAS_ARG(opcode)) oparg = NEXTARG(); dispatch_opcode: switch (opcode) { case NOP: goto fast_next_opcode; case LOAD_FAST: ... } } }
enum why_code{ WHY_NOT = 0x0001, WHY_EXCEPTION = 0x0002 WHY_RERAISE = 0x0004 WHY_RETURN = 0x0008 WHY_BREAK = 0x0010 WHY_CONTINUE = 0x0020 WHY_YIELD = 0x0040 };
|
d.Python运行时环境初探
PyThreadState实现线程,PyInterpreterState实现进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| [pystate.h] typedef struct _is{ struct _is* next; struct _ts* tstate_head;
PyObject* modules; PyObject* sysdict; PyObject* builtins; ... } PyInterpreterState;
typedef struct _ts{ struct _ts* next; PyInterpreterState* iterp; struct _frame* frame; int recursion_depth; ... PyObject* dict; ... long thread_id; } PyThreadState;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| [ceval.c] PyObject* PyEval_EvalFrameEx(PyFrameObject* f, int throwflag){ ... PyThreadState* tstate = PyThreadState_GET(); ... tstate->frame = f; co = f->f_code; name = co->co_names; consts = co->co_consts; ...
for(;;){ ... } }
PyFrameObject* PyFrame_New(PyThreadState* tstate, PyCodeObject* code, PyObject* globals, PyObject* locals){ PyFrameObject* back = tstate->frame; PyFrameObject* f; .... f = PyObject_GC_Resize(PyFrameObject,f,extras); .... f->f_back = back; f->f_tstate = tstate; ... return f; }
|