PyCodeObject)PyCodeObject C 結構體。.pyc 檔案是位元組碼在磁碟上的序列化形式。import 模組時。python test.py 會編譯並執行,但不生成 test.pyc。import util 會生成 util.pyc。python -m py_compile test.py。.py 和 .pyc 時,比對修改時間,.py 較新則重新編譯。typedef struct {
PyObject_HEAD
int co_argcount; // 位置參數個數
int co_nlocals; // 區域變數個數
int co_stacksize; // 堆疊大小
int co_flags;
PyObject *co_code; // 位元組碼指令序列 (bytes)
PyObject *co_consts; // 常數表 (元組)
PyObject *co_names; // 符號名稱表 (全域/屬性名)
PyObject *co_varnames; // 區域變數名稱表
PyObject *co_freevars; // 閉包自由變數
PyObject *co_cellvars; // 供內層函數引用的變數
PyObject *co_filename; // 原始碼檔名
PyObject *co_name; // 模組/函數/類別名稱
int co_firstlineno; // 起始行號
PyObject *co_lnotab; // 位元組碼偏移量對應行號表
void *co_zombieframe; // 最佳化用
} PyCodeObject;

包含:Magic Number (版本標識) + Timestamp (修改時間) + Marshaled PyCodeObject。
test.pys = "hello"
def func():
print(s)
func()
>>> code = compile(open('test.py').read(), 'test.py', 'exec')
>>> code.co_argcount
0
>>> code.co_names
('s', 'func')
>>> code.co_varnames
('s', 'func')
>>> code.co_consts
('hello', <code object func at 0x...>, None)
>>> code.co_code
'd\x00\x00Z\x00\x00d\x01\x00\x84\x00\x00Z\x01\x00e\x01\x00\x83\x00\x00\x01d\x02\x00S'
func 的 PyCodeObject>>> func_code = code.co_consts[1]
>>> func_code.co_argcount
0
>>> func_code.co_names
('s',)
>>> func_code.co_consts
(None,)
>>> func_code.co_code
't\x00\x00GHd\x00\x00S'
co_code 為位元組流,格式:[opcode, oparg_low, oparg_high, ...]。
LOAD_CONST=100)。co_consts 或 co_names 索引。dis 模組>>> import dis
>>> dis.dis(code)
1 0 LOAD_CONST 0 ('hello')
3 STORE_NAME 0 (s)
2 6 LOAD_CONST 1 (<code object func>)
9 LOAD_CONST 2 ('func')
12 MAKE_FUNCTION 0
15 STORE_NAME 1 (func)
4 18 LOAD_NAME 1 (func)
21 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
24 POP_TOP
25 LOAD_CONST 3 (None)
28 RETURN_VALUE
PyFrameObject模擬 C 執行時的堆疊幀,鏈結形成呼叫堆疊。
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; // 運算堆疊頂
...
} PyFrameObject;
模組層級幀 執行 test.py 位元組碼:
LOAD_CONST 0 ('hello') → 推入堆疊STORE_NAME 0 (s) → 彈出堆疊,存入 f_locals['s']LOAD_CONST 1 (func_code) → 推入MAKE_FUNCTION → 建立函數物件,綁定 func_code 及閉包環境STORE_NAME 1 (func) → 存入區域LOAD_NAME 1 (func) → 取得函數物件CALL_FUNCTION → **建立新幀** 執行 func_code函數幀 執行 func:
LOAD_GLOBAL 0 (print) → 從 f_globals 找 printLOAD_DEREF 0 (s) → 從閉包 (f_locals 的 cell) 取 sCALL_FUNCTION 1 → 呼叫 print(s)RETURN_VALUE → 返回 None,銷毀幀
import sys
def func():
frame = sys._getframe()
print("Locals:", frame.f_locals)
print("Globals keys:", list(frame.f_globals.keys())[:5])
print("Caller locals:", frame.f_back.f_locals)
print("s =", frame.f_locals['s'])
s = "hello"
func()
Python 採用「編譯為位元組碼 + 棧式虛擬機解釋執行」架構。理解 PyCodeObject、PyFrameObject、指令集與命名空間機制,有助於效能調優、除錯、以及開發工具鏈 (如型別檢查器、JIT 編譯器)。