1. プロセスの概要
Python はまずコード (.py ファイル) をバイトコードにコンパイルし、バイトコード仮想マシンに渡します。その後、仮想マシンはバイトコード命令を 1 つずつ実行してプログラムの実行を完了します。
2.バイトコード
バイトコードはPython仮想マシンプログラムのPyCodeObjectオブジェクトに相当します。
.pyc ファイルはディスク上のバイトコードを表現したものです。
3. pycファイル
PyCodeObjectオブジェクトはモジュールのロード時、つまりインポート時に作成されます。
Pythonのtest.pyはtest.pyをバイトコードにコンパイルして実行用に解釈しますが、test.pycは生成しません。
test.pyがimport utilなどの他のモジュールをロードすると、Pythonはutil.pyをバイトコードにコンパイルし、util.pycを生成し、そのバイトコードを解釈して実行します。
test.pycを生成したい場合は、Pythonの組み込みモジュールpy_compile/compileallを使用してコンパイルできます。
モジュールをロードするときに、.py と .pyc の両方が存在する場合、Python は .pyc のコンパイル時刻が .py の変更時刻よりも早い場合、.py が再コンパイルされ、.pyc が再コンパイルされます。更新します。
4. PyCodeObject
Pythonコードをコンパイルした結果がPyCodeObjectオブジェクトです。
typedef struct {
PyObject_HEAD
int co_argcount; /* 位置パラメータの数*/
int co_nlocals; /* スタックサイズ*/
int co_flags ;
PyObject *co_code; /* バイトコード命令シーケンス*/
PyObject *co_consts; /* すべての定数セット*/
PyObject *co_varnames; /* のセットローカル変数名 */
PyObject *co_freevars; /* クロージャに使用される変数名のセット */
PyObject *co_cellvars; /* 内部の入れ子関数によって参照される変数名のセット */
/* 残りはありませんcount for hash/cmp */
PyObject *co_filename; /* コードが配置されているファイル名 */
PyObject *co_name; /* モジュール名|関数名|クラス名*/
int co_firstlineno; block ファイル内の開始行番号 */
PyObject *co_lnotab; /* バイトコード命令と行番号の対応 */
void *co_zombieframe; /* 最適化のみ (frameobject.c を参照) */
} PyCodeObject ;