| 
                         Python虚拟机的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图: 
  
假如test.py用C语言来实现,会是下面这个样子: 
- const char *s = “hello”; 
 
-  
 
- void func() { 
 
-     printf(“%sn”, s); 
 
- } 
 
-  
 
- int main() { 
 
-     func(); 
 
-     return 0; 
 
- } 
 
 
Python虚拟机的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。 
7.1 PyFrameObject 
- 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;    /* 运行时栈顶 */ 
 
-     ……. 
 
- } 
 
 
那么对应Python的运行时栈就是这样子: 
  
7.2 执行指令 
执行test.py的字节码时,会先创建一个栈帧,以下用f表示当前栈帧,执行过程注释如下: 
test.py的符号名集合和常量集合 
- co.co_names   (‘s’, ’func’) 
 
- co.co_consts  (‘hello’, <code object func at 0x2aaeeec57110, file ”test.py”, line 3>, None) 
 
 
test.py的指令序列 
  
上面的CALL_FUNCTION指令执行时,会创建新的栈帧,并执行func的字节码指令,以下用f表示当前栈帧,func的字节码执行过程如下: 
func函数的符号名集合和常量集合 
- func.co_names       (‘s’,) 
 
- func.co_consts      (None,) 
  
 
func函数的指令序列 
  
7.3 查看栈帧 
如果你想查看当前栈帧,Python提供了sys._getframe()方法可以获取当前栈帧,你只需要在代码里加入代码如下: 
- def func(): 
 
-     import sys 
 
-     frame = sys._getframe() 
 
-     print frame.f_locals 
 
-     print frame.f_globals 
 
-     print frame.f_back.f_locals 
 
-     #你可以打印frame的各个域 
 
-     print s   
 
 
原文链接:http://tech.uc.cn/?p=1932                         (编辑:91站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |