12、sys._getframe()

 1 def func(): 
 2     import sys 
 3     frame = sys._getframe()
 4     frame0 =  sys._getframe(0)
 5     frame1 =  sys._getframe(1)
 6     
 7     print('1:',frame)
 8     print('2:',frame0)
 9     print('3:',frame1)
10     print('4:',frame.f_code)
11     print('5:',frame.f_locals)
12     print('6:',frame.f_globals) 
13     print('7:',frame.f_back.f_locals)
14     print('8:',frame.f_code.co_filename)
15     print('9:',frame.f_code.co_name ) 
16     #你可以打印frame的各个域
17     print('10:',frame0.f_code)
18     print('11:',frame0.f_locals)
19     print('12:',frame0.f_globals) 
20     print('13:',frame0.f_code.co_filename)
21     print('14:',frame0.f_code.co_name )
22 
23     print('15:',frame1.f_code)
24     print('16:',frame1.f_locals)
25     print('17:',frame1.f_globals) 
26     print('18:',frame1.f_code.co_filename)
27     print('19:',frame1.f_code.co_name )
28      
29 func()
 1 1: <frame object at 0x000001F52F081108>
 2 2: <frame object at 0x000001F52F081108>
 3 3: <frame object at 0x000001F52F2B9828>
 4 4: <code object func at 0x000001F52F725AE0, file "test.py", line 1>
 5 5: {'frame1': <frame object at 0x000001F52F2B9828>, 'frame0': <frame object at 0x000001F52F081108>, 'frame': <frame object at 0x000001F52F081108>, 'sys': <module 'sys' (built-in)>}
 6 6: {'__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F52F729A58>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__file__': 'test.py', '__package__': None, '__spec__': None, 'func': <function func at 0x000001F52F936950>}
 7 7: {'__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F52F729A58>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__file__': 'test.py', '__package__': None, '__spec__': None, 'func': <function func at 0x000001F52F936950>}
 8 8: test.py
 9 9: func
10 10: <code object func at 0x000001F52F725AE0, file "test.py", line 1>
11 11: {'frame1': <frame object at 0x000001F52F2B9828>, 'frame0': <frame object at 0x000001F52F081108>, 'frame': <frame object at 0x000001F52F081108>, 'sys': <module 'sys' (built-in)>}
12 12: {'__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F52F729A58>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__file__': 'test.py', '__package__': None, '__spec__': None, 'func': <function func at 0x000001F52F936950>}
13 13: test.py
14 14: func
15 15: <code object <module> at 0x000001F52F7626F0, file "test.py", line 1>
16 16: {'__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F52F729A58>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__file__': 'test.py', '__package__': None, '__spec__': None, 'func': <function func at 0x000001F52F936950>}
17 17: {'__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F52F729A58>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__file__': 'test.py', '__package__': None, '__spec__': None, 'func': <function func at 0x000001F52F936950>}
18 18: test.py
19 19: <module>

假如test.py用C语言来实现,会是下面这个样子:

  1. const char *s = “hello”; 
  2.  
  3. void func() { 
  4.     printf(“%s ”, s); 
  5.  
  6. int main() { 
  7.     func(); 
  8.     return 0; 

Python虚拟机的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。

7.1 PyFrameObject

  1. typedef struct _frame { 
  2.     PyObject_VAR_HEAD 
  3.     struct _frame *f_back;    /* 调用者的帧 */ 
  4.     PyCodeObject *f_code;     /* 帧对应的字节码对象 */ 
  5.     PyObject *f_builtins;     /* 内置名字空间 */ 
  6.     PyObject *f_globals;      /* 全局名字空间 */ 
  7.     PyObject *f_locals;       /* 本地名字空间 */ 
  8.     PyObject **f_valuestack;  /* 运行时栈底 */ 
  9.     PyObject **f_stacktop;    /* 运行时栈顶 */ 
  10.     ……. 

那么对应Python的运行时栈就是这样子:

7.2 执行指令

执行test.py的字节码时,会先创建一个栈帧,以下用f表示当前栈帧,执行过程注释如下:

test.py的符号名集合和常量集合

  1. co.co_names   (‘s’, ’func’) 
  2. co.co_consts  (‘hello’, <code object func at 0x2aaeeec57110, file ”test.py”, line 3>, None) 

test.py的指令序列

上面的CALL_FUNCTION指令执行时,会创建新的栈帧,并执行func的字节码指令,以下用f表示当前栈帧,func的字节码执行过程如下:

func函数的符号名集合和常量集合

  1. func.co_names       (‘s’,) 
  2. func.co_consts      (None,) 

func函数的指令序列

原文地址:https://www.cnblogs.com/lixiaofou/p/8252343.html