1 #!/user/bin/env python 2 # -*- coding:utf-8 -*- 3 import dis 4 import inspect 5 frame = None 6 7 8 def foo(): 9 bar() 10 11 12 def bar(): 13 global frame 14 frame = inspect.currentframe() 15 16 17 # python.exe会用一个叫做PyEval_EvalFramEx(c函数)去执行foo函数,首先会创建一个栈帧(stack frame) 18 """ 19 python中一切皆对象,栈帧是一个对象(栈帧对象),字节码对象 20 当foo调用子函数bar,又会创建一个栈帧 21 所有的栈帧都是分配在堆内存上(堆内存不释放就一直存在),这就决定了栈帧可以独立于调用者存在 22 """ 23 24 print(dis.dis(foo)) 25 foo() 26 # 打印出bar的栈帧 27 print(frame.f_code.co_name) 28 # 打印出foo的栈帧 29 caller_frame = frame.f_back 30 print(caller_frame) 31 32 33 def gen_func(): 34 yield 1 35 name = 'zy' 36 yield 2 37 age = 21 38 return 'ok' 39 40 41 gen = gen_func() 42 print(dis.dis(gen)) 43 44 print(gen.gi_frame.f_lasti) 45 print(gen.gi_frame.f_locals) 46 next(gen) 47 print(gen.gi_frame.f_lasti) 48 print(gen.gi_frame.f_locals) 49 next(gen) 50 print(gen.gi_frame.f_lasti) 51 print(gen.gi_frame.f_locals) 52 53 # 我们可以控制函数的执行和暂停
9 0 LOAD_GLOBAL 0 (bar) 2 CALL_FUNCTION 0 4 POP_TOP 6 LOAD_CONST 0 (None) 8 RETURN_VALUE None bar <frame at 0x000002BBCE39DE58, file 'demo.py', line 9, code foo> <generator object gen_func at 0x000002BBD0218930> C:UsersAdministratorPythonimooc>python demo.py 9 0 LOAD_GLOBAL 0 (bar) 2 CALL_FUNCTION 0 4 POP_TOP 6 LOAD_CONST 0 (None) 8 RETURN_VALUE None bar <frame at 0x0000025478CADE58, file 'demo.py', line 9, code foo> 34 0 LOAD_CONST 1 (1) 2 YIELD_VALUE 4 POP_TOP 35 6 LOAD_CONST 2 ('zy') 8 STORE_FAST 0 (name) 36 10 LOAD_CONST 3 (2) 12 YIELD_VALUE 14 POP_TOP 37 16 LOAD_CONST 4 (21) 18 STORE_FAST 1 (age) 38 20 LOAD_CONST 5 ('ok') 22 RETURN_VALUE None -1 {} 2 {} 12 {'name': 'zy'}