[解決済み] dis.disの出力はどのように理解すればよいのでしょうか?
質問
私は
dis (Pythonのバイトコードのディスアセンブラ)
. の出力をどのように解釈すればよいのでしょうか?
dis.dis
(または
dis.disassemble
)?
.
以下は非常に具体的な例です(Python 2.7.3の場合)。
dis.dis("heapq.nsmallest(d,3)")
0 BUILD_SET 24933
3 JUMP_IF_TRUE_OR_POP 11889
6 JUMP_FORWARD 28019 (to 28028)
9 STORE_GLOBAL 27756 (27756)
12 LOAD_NAME 29811 (29811)
15 STORE_SLICE+0
16 LOAD_CONST 13100 (13100)
19 STORE_SLICE+1
なるほど
JUMP_IF_TRUE_OR_POP
などはバイトコード命令
(です(ただし、面白いことに
BUILD_SET
として動作すると思われますが、このリストには出てきません。
BUILD_TUPLE
)
. 右側の数字がメモリ確保で、左側の数字が
ゴー
の数字だと思うのですが... 私は彼らが
はほとんど
は毎回 3 ずつ増加します (ただし、完全ではありません)。
もし私が
dis.dis("heapq.nsmallest(d,3)")
を関数の中に入れると
def f_heapq_nsmallest(d,n):
return heapq.nsmallest(d,n)
dis.dis("f_heapq(d,3)")
0 BUILD_TUPLE 26719
3 LOAD_NAME 28769 (28769)
6 JUMP_ABSOLUTE 25640
9 <44> # what is <44> ?
10 DELETE_SLICE+1
11 STORE_SLICE+1
どのように解決するのですか?
ソースコードを含む文字列を逆アセンブルしようとしていますが、それは
dis.dis
ではサポートされていません。文字列の引数では、バイトコードを含むかのように文字列を扱います(関数
disassemble_string
で
dis.py
). つまり、ソース コードをバイト コードとして誤って解釈することに基づいて、無意味な出力が表示されているのです。
Python 3では事情が異なり
dis.dis
は文字列の引数をコンパイルします
を逆アセンブルする前にコンパイルします。
Python 3.2.3 (default, Aug 13 2012, 22:28:10)
>>> import dis
>>> dis.dis('heapq.nlargest(d,3)')
1 0 LOAD_NAME 0 (heapq)
3 LOAD_ATTR 1 (nlargest)
6 LOAD_NAME 2 (d)
9 LOAD_CONST 0 (3)
12 CALL_FUNCTION 2
15 RETURN_VALUE
Python 2 では、コードを自分でコンパイルしてから
dis.dis
:
Python 2.7.3 (default, Aug 13 2012, 18:25:43)
>>> import dis
>>> dis.dis(compile('heapq.nlargest(d,3)', '<none>', 'eval'))
1 0 LOAD_NAME 0 (heapq)
3 LOAD_ATTR 1 (nlargest)
6 LOAD_NAME 2 (d)
9 LOAD_CONST 0 (3)
12 CALL_FUNCTION 2
15 RETURN_VALUE
数字は何を意味するのか?数字は
1
はこのバイトコードがコンパイルされたソースコード内の行番号です。左の列の数字はバイトコード内の命令のオフセットで、右の列の数字は
opargs
. 実際のバイトコードを見てみましょう。
>>> co = compile('heapq.nlargest(d,3)', '<none>', 'eval')
>>> co.co_code.encode('hex')
'6500006a010065020064000083020053'
バイトコードのオフセット0には
65
のオペコードは
LOAD_NAME
というオペコードと
0000
である場合、(オフセット 3 で)
6a
はオペコード
LOAD_ATTR
である。
0100
のようになります。引数はリトルエンディアンの順であることに注意してください。
0100
は数字1である。文書化されていない
opcode
モジュールにはテーブル
opname
は、各オペコードの名前を与えており
opmap
はそれぞれの名前に対応するオペコードを与えます。
>>> opcode.opname[0x65]
'LOAD_NAME'
opargの意味はopcodeに依存し、その全容はCPython仮想マシンの実装を読む必要があります
で
ceval.c
. の場合
LOAD_NAME
と
LOAD_ATTR
へのインデックスである。
co_names
プロパティのインデックスです。
>>> co.co_names
('heapq', 'nlargest', 'd')
については
LOAD_CONST
へのインデックスです。
co_consts
プロパティへのインデックスです。
>>> co.co_consts
(3,)
については
CALL_FUNCTION
では、関数に渡す引数の数で、下位バイトに通常の引数の数、上位バイトにキーワード引数の数で16ビットでエンコードされています。
関連
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] for'ループでインデックスにアクセスする?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] print関数の出力をフラッシュする(pythonの出力をバッファリング解除する)にはどうすればよいですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
-
[解決済み] ファブリック経由でデプロイユーザとしてvirtualenvを有効化する
-
[解決済み] Pythonの検索パスを他のソースに展開する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] Pythonです。未束縛のメソッドを束縛する?
-
[解決済み] dict を txt ファイルに書き、それを読み取る?
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] Cythonのコードを含むPythonパッケージはどのように構成すればよいのでしょうか?
-
[解決済み] Pythonでファイルの読み込みと上書きをする
-
[解決済み] Python 言語を決定するには?
-
[解決済み] Pythonの文字列書式をリストで使う
-
[解決済み] Django filter queryset __in for *every* item in list