Python 2.6.2のpycファイルフォーマット
関連リンク:
Pythonを例に高度なプログラミング言語プログラムのwire formatと検証を議論する
Python 2.6.2のバイトコード命令セット一覧
.pycファイルは何ですか.
Pythonソースコードのコンパイルの結果は
PyCodeObject(以下、PyCodeObjectの例を「コードオブジェクト」と略称する)では、各役割ドメインに対応するコードオブジェクトがコンパイルされ、co_codeというPyStringObjectはコードオブジェクトのバイトコードを保存している.
Pythonソースファイルはモジュールです.各モジュールの最上位レベルのコードオブジェクトは
marshalはシーケンス化後に得る.pycファイル.marshalはlittle-endianバイト順でデータをシーケンス化する.
関数、クラスの定義など、最上位の役割ドメインにネストされている役割ドメインは、対応するコードオブジェクトはどこにありますか?それぞれが上の役割ドメインのコードオブジェクトにおとなしく横たわっているco_const(定数プール)ドメインには、上位レベルのコードオブジェクトがネストされているため、下の他の役割ドメインを含むコードオブジェクトがネストされています.
PyCodeObjectの構造とmarshalのシーケンス化ロジックは、前のセグメントの2つのリンクを参照してください.
Python 2.6.2のpycファイルの構造
以上、整数型のドメインには長さが表示され、他のドメインにはタイプが表示されます.ファイルヘッダと後ろのPyCodeObjectの境界線がはっきり見えるように横線で特別に表記してあります.
キーバイトコードはPyStringObjectタイプのオブジェクトに存在するため、このタイプがmarshalでシーケンス化された構造も説明する必要があります.
この2つの構造を理解した後、Python 2.6で発売することができます.2のpycファイルでは、アドレスが0 x 1 Aから始まる4バイト整数で、最上位コードオブジェクトのバイトコードの長さを識別し、長さがlenであると仮定する.0 x 1 Eからlen長のデータが最上位コードオブジェクトのバイトコードである.
pyc_についてmagic
pyc_magicは2バイトの整数で、r(0 x 0 D 0 x 0 Aはr)が加算されます.このように計算されます.
(
Python 2.6 a 1のPython/import.c )
△marshalが書くときはlittle-endianバイト順を保つことに注意して、rは後ろに走った.
magicにこのようなデータが含まれているのはrが改行文字なので、もし.pycファイルがテキストモードで開く編集されるとmagicが乱れ、Python解釈器がこの破損をロードしようとしています.pycファイルの場合、問題が見つかります.
しかし、その62161はどうやって来たのですか.読書を通して
Include/code.hの注釈では、主要なPythonリリースごとに特別な数字があり、バージョン間で異なることが観察されます.
するとpyc_magicの役割は3つあります.
1、断るのはまったく正常ではない.pycのファイル、例えば普通のテキスト、ピクチャ、音楽、または他のバイナリフォーマット.ファイルの最初の4バイトをチェックすると、多くの無効なファイルが効果的に削除されます.
2、テキストエディタの編集によって破損したファイルを拒否します.
3、対応しないPython解釈器の生成を拒否する.pycファイル.異なるPythonバージョンのmarshalアルゴリズムは異なる可能性があり、仮想マシンが採用するバイトコード命令セットも異なる可能性があるため、念のため異なるバージョンのPython解釈器が生成する.pycファイルは互換性がないと考えられています.
mtimeについて
PyCodeObjectはシーケンス化する.pycファイルの場合、対応するソースファイルの修正時間とともに記録されます.対応するソースファイルが変更すると、そのmtimeが変化し、以前に生成する.pycファイルのmtimeはソースファイルの新しいmtimeと一致しません.これによりPythonインタプリタは、ソースファイルの更新を発見し、再生成することができる.pycファイル.
Python解釈器生成pycファイルは一般的にimportメカニズムでアクティブ化され、読む
Python/import.c importのpyc_が表示されますmagicとmtimeのチェックと書き込み.
ゆうべ作った
Python 2.6.2のバイトコード命令セット一覧、興味のある方はご覧ください~
実際に一つ解読する.pycファイルのバイトコード
例えば、このようなPythonソース:(手当たり次第に書いたので、内容を気にしないでください)
demo.py
Python解釈器にdemoにコンパイルする.pyc.他のPythonプログラムでimport demoを勝手に使えば、このファイルを手に入れることができます.ファイルの内容は次のとおりです.
本明細書の前半の解析によれば、最上位コードのバイトコード長は0 x 66=102バイトであり、0 x 1 E−0 x 83の範囲内にある.興味のある方は参考にしてください
Python命令セットリストバイトコード命令を自分で解読してみましょう.
バイトコードの先頭を見ると、まず0 x 64で、これはLOAD_です.CONST命令は、パラメータがあるので、次の2バイト、0 x 00 0 0 x 00、すなわちパラメータが0(little-endianバイト順に注意)である.LOAD_CONST 0は、定数プールの下に0と表記されたオブジェクトを評価スタックに押し付ける.
次に0 x 64、パラメータの0 x 05 0 x 00を接続するとLOAD_CONST 5は,定数プールの下に5と表記されたオブジェクトを評価スタックに押し付ける.
後のバイトコードも法に基づいて類推して認識することができる.
実際にPython標準ライブラリにはバイトコードを抽出するライブラリ、disモジュールがあります.自分で分析するのが面倒ならdisに解決してもらえばいい.
(次のコードではdis.dis(code)の結果が最上位コードオブジェクトのバイトコードであり、
書式:行番号オフセット指令名パラメータ(カッコ内はパラメータの注記))
P.S.実はこの文は単独で火星を见ています......私は别の1帖をもっときれいにするために分析します.pycファイルフォーマットの部分が取り外されました.もう一つの投稿は:
Pythonを例に高度なプログラミング言語プログラムのwire formatと検証を議論する
Pythonを例に高度なプログラミング言語プログラムのwire formatと検証を議論する
Python 2.6.2のバイトコード命令セット一覧
.pycファイルは何ですか.
Pythonソースコードのコンパイルの結果は
PyCodeObject(以下、PyCodeObjectの例を「コードオブジェクト」と略称する)では、各役割ドメインに対応するコードオブジェクトがコンパイルされ、co_codeというPyStringObjectはコードオブジェクトのバイトコードを保存している.
Pythonソースファイルはモジュールです.各モジュールの最上位レベルのコードオブジェクトは
marshalはシーケンス化後に得る.pycファイル.marshalはlittle-endianバイト順でデータをシーケンス化する.
関数、クラスの定義など、最上位の役割ドメインにネストされている役割ドメインは、対応するコードオブジェクトはどこにありますか?それぞれが上の役割ドメインのコードオブジェクトにおとなしく横たわっているco_const(定数プール)ドメインには、上位レベルのコードオブジェクトがネストされているため、下の他の役割ドメインを含むコードオブジェクトがネストされています.
PyCodeObjectの構造とmarshalのシーケンス化ロジックは、前のセグメントの2つのリンクを参照してください.
Python 2.6.2のpycファイルの構造
============== <- 。
pyc_magic (=0xD1 0xF2 0x0D 0x0A,4 , .pyc )
mtime (4 ,.pyc )
============== <- PyCodeObject 。
TYPE_CODE (='c',1 ,PyCodeObject )
co_argscount (4 , )
co_nlocals (4 , ( ) )
co_stacksize (4 , )
co_flags (4 , )
co_code (PyStringObject, )
co_consts (PyTupleObject, )
co_names (PyTupleObject, )
co_varnames (PyTupleObject, )
co_freevars (PyTupleObject, )
co_cellvars (PyTupleObject, )
co_filename (PyStringObject, )
co_firstlineno(4 , )
co_lnotab (PyStringObject, )
============== <- PyCodeObject 。
以上、整数型のドメインには長さが表示され、他のドメインにはタイプが表示されます.ファイルヘッダと後ろのPyCodeObjectの境界線がはっきり見えるように横線で特別に表記してあります.
キーバイトコードはPyStringObjectタイプのオブジェクトに存在するため、このタイプがmarshalでシーケンス化された構造も説明する必要があります.
=========== <- PyStringObject
TYPE_STRING(='s',1 ,PyStringObject )
length (4 , )
data (byte , )
=========== <- PyStringObject
この2つの構造を理解した後、Python 2.6で発売することができます.2のpycファイルでは、アドレスが0 x 1 Aから始まる4バイト整数で、最上位コードオブジェクトのバイトコードの長さを識別し、長さがlenであると仮定する.0 x 1 Eからlen長のデータが最上位コードオブジェクトのバイトコードである.
pyc_についてmagic
pyc_magicは2バイトの整数で、r(0 x 0 D 0 x 0 Aはr)が加算されます.このように計算されます.
(
Python 2.6 a 1のPython/import.c )
#define MAGIC (62161 | ((long)'\r'<<16) | ((long)'
'<<24))
△marshalが書くときはlittle-endianバイト順を保つことに注意して、rは後ろに走った.
magicにこのようなデータが含まれているのはrが改行文字なので、もし.pycファイルがテキストモードで開く編集されるとmagicが乱れ、Python解釈器がこの破損をロードしようとしています.pycファイルの場合、問題が見つかります.
しかし、その62161はどうやって来たのですか.読書を通して
Include/code.hの注釈では、主要なPythonリリースごとに特別な数字があり、バージョン間で異なることが観察されます.
するとpyc_magicの役割は3つあります.
1、断るのはまったく正常ではない.pycのファイル、例えば普通のテキスト、ピクチャ、音楽、または他のバイナリフォーマット.ファイルの最初の4バイトをチェックすると、多くの無効なファイルが効果的に削除されます.
2、テキストエディタの編集によって破損したファイルを拒否します.
3、対応しないPython解釈器の生成を拒否する.pycファイル.異なるPythonバージョンのmarshalアルゴリズムは異なる可能性があり、仮想マシンが採用するバイトコード命令セットも異なる可能性があるため、念のため異なるバージョンのPython解釈器が生成する.pycファイルは互換性がないと考えられています.
mtimeについて
PyCodeObjectはシーケンス化する.pycファイルの場合、対応するソースファイルの修正時間とともに記録されます.対応するソースファイルが変更すると、そのmtimeが変化し、以前に生成する.pycファイルのmtimeはソースファイルの新しいmtimeと一致しません.これによりPythonインタプリタは、ソースファイルの更新を発見し、再生成することができる.pycファイル.
Python解釈器生成pycファイルは一般的にimportメカニズムでアクティブ化され、読む
Python/import.c importのpyc_が表示されますmagicとmtimeのチェックと書き込み.
ゆうべ作った
Python 2.6.2のバイトコード命令セット一覧、興味のある方はご覧ください~
実際に一つ解読する.pycファイルのバイトコード
例えば、このようなPythonソース:(手当たり次第に書いたので、内容を気にしないでください)
demo.py
class A():
x = 1
print(A.x) # 1
# increment A.x by 2
A.x += 2
print(A.x) # 3
# create an instance of A
a = A()
print(a.x) # 3
# increment A.x by 4
a.x += 4
print(a.x) # 7
print(A.x) # 3
Python解釈器にdemoにコンパイルする.pyc.他のPythonプログラムでimport demoを勝手に使えば、このファイルを手に入れることができます.ファイルの内容は次のとおりです.
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 D1 F2 0D 0A B3 34 04 4A 63 00 00 00 00 00 00 00 ..?.Jc.......
00000010 00 03 00 00 00 40 00 00 00 73 66 00 00 00 64 00 [email protected].
00000020 00 64 05 00 64 01 00 84 00 00 83 00 00 59 5A 00 .d..d..?.?.YZ.
00000030 00 65 00 00 69 01 00 47 48 65 00 00 04 69 01 00 .e..i..GHe...i..
00000040 64 02 00 37 02 5F 01 00 65 00 00 69 01 00 47 48 d..7._..e..i..GH
00000050 65 00 00 83 00 00 5A 02 00 65 02 00 69 01 00 47 e..?.Z..e..i..G
00000060 48 65 02 00 04 69 01 00 64 03 00 37 02 5F 01 00 He...i..d..7._..
00000070 65 02 00 69 01 00 47 48 65 00 00 69 01 00 47 48 e..i..GHe..i..GH
00000080 64 04 00 53 28 06 00 00 00 74 01 00 00 00 41 63 d..S(....t....Ac
00000090 00 00 00 00 00 00 00 00 01 00 00 00 42 00 00 00 ............B...
000000A0 73 0E 00 00 00 65 00 00 5A 01 00 64 00 00 5A 02 s....e..Z..d..Z.
000000B0 00 52 53 28 01 00 00 00 69 01 00 00 00 28 03 00 .RS(....i....(..
000000C0 00 00 74 08 00 00 00 5F 5F 6E 61 6D 65 5F 5F 74 ..t....__name__t
000000D0 0A 00 00 00 5F 5F 6D 6F 64 75 6C 65 5F 5F 74 01 ....__module__t.
000000E0 00 00 00 78 28 00 00 00 00 28 00 00 00 00 28 00 ...x(....(....(.
000000F0 00 00 00 73 07 00 00 00 64 65 6D 6F 2E 70 79 52 ...s....demo.pyR
00000100 00 00 00 00 01 00 00 00 73 02 00 00 00 06 01 69 ........s......i
00000110 02 00 00 00 69 04 00 00 00 4E 28 00 00 00 00 28 ....i....N(....(
00000120 03 00 00 00 52 00 00 00 00 52 03 00 00 00 74 01 ....R....R....t.
00000130 00 00 00 61 28 00 00 00 00 28 00 00 00 00 28 00 ...a(....(....(.
00000140 00 00 00 73 07 00 00 00 64 65 6D 6F 2E 70 79 74 ...s....demo.pyt
00000150 08 00 00 00 3C 6D 6F 64 75 6C 65 3E 01 00 00 00 ....<module>....
00000160 73 10 00 00 00 13 03 08 03 0F 01 08 03 09 01 08 s...............
00000170 03 0F 01 08 01 .....
本明細書の前半の解析によれば、最上位コードのバイトコード長は0 x 66=102バイトであり、0 x 1 E−0 x 83の範囲内にある.興味のある方は参考にしてください
Python命令セットリストバイトコード命令を自分で解読してみましょう.
バイトコードの先頭を見ると、まず0 x 64で、これはLOAD_です.CONST命令は、パラメータがあるので、次の2バイト、0 x 00 0 0 x 00、すなわちパラメータが0(little-endianバイト順に注意)である.LOAD_CONST 0は、定数プールの下に0と表記されたオブジェクトを評価スタックに押し付ける.
次に0 x 64、パラメータの0 x 05 0 x 00を接続するとLOAD_CONST 5は,定数プールの下に5と表記されたオブジェクトを評価スタックに押し付ける.
後のバイトコードも法に基づいて類推して認識することができる.
実際にPython標準ライブラリにはバイトコードを抽出するライブラリ、disモジュールがあります.自分で分析するのが面倒ならdisに解決してもらえばいい.
(次のコードではdis.dis(code)の結果が最上位コードオブジェクトのバイトコードであり、
書式:行番号オフセット指令名パラメータ(カッコ内はパラメータの注記))
E:\Python26>python
Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis, marshal
>>> f = open('demo.pyc', 'rb')
>>> magic = f.read(4)
>>> mtime = f.read(4)
>>> code = marshal.load(f)
>>> dis.dis(code)
1 0 LOAD_CONST 0 ('A')
3 LOAD_CONST 5 (())
6 LOAD_CONST 1 (<code object A at 01707EC0, file "demo.py", line 1>)
9 MAKE_FUNCTION 0
12 CALL_FUNCTION 0
15 BUILD_CLASS
16 STORE_NAME 0 (A)
4 19 LOAD_NAME 0 (A)
22 LOAD_ATTR 1 (x)
25 PRINT_ITEM
26 PRINT_NEWLINE
7 27 LOAD_NAME 0 (A)
30 DUP_TOP
31 LOAD_ATTR 1 (x)
34 LOAD_CONST 2 (2)
37 INPLACE_ADD
38 ROT_TWO
39 STORE_ATTR 1 (x)
8 42 LOAD_NAME 0 (A)
45 LOAD_ATTR 1 (x)
48 PRINT_ITEM
49 PRINT_NEWLINE
11 50 LOAD_NAME 0 (A)
53 CALL_FUNCTION 0
56 STORE_NAME 2 (a)
12 59 LOAD_NAME 2 (a)
62 LOAD_ATTR 1 (x)
65 PRINT_ITEM
66 PRINT_NEWLINE
15 67 LOAD_NAME 2 (a)
70 DUP_TOP
71 LOAD_ATTR 1 (x)
74 LOAD_CONST 3 (4)
77 INPLACE_ADD
78 ROT_TWO
79 STORE_ATTR 1 (x)
16 82 LOAD_NAME 2 (a)
85 LOAD_ATTR 1 (x)
88 PRINT_ITEM
89 PRINT_NEWLINE
17 90 LOAD_NAME 0 (A)
93 LOAD_ATTR 1 (x)
96 PRINT_ITEM
97 PRINT_NEWLINE
98 LOAD_CONST 4 (None)
101 RETURN_VALUE
>>> quit()
P.S.実はこの文は単独で火星を见ています......私は别の1帖をもっときれいにするために分析します.pycファイルフォーマットの部分が取り外されました.もう一つの投稿は:
Pythonを例に高度なプログラミング言語プログラムのwire formatと検証を議論する