26

disPython のバイトコードとそのモジュールを理解するのに非常に苦労しています。

import dis
def func():
   x = 1
dis.dis(func)

上記のコードをインタープリターに入力すると、次の出力が生成されます。

    0 LOAD_CONST                  1(1)
    3 STORE_FAST                  0(x)
    6 LOAD_CONST                  0(NONE)
    9 RETURN_VALUE

例えば:

LOAD_CONST、、 、STORE_FASTのような数字は何を意味しますか?0369

この情報を見つけることができる特定のリソースをいただければ幸いです。

4

1 に答える 1

44

バイトコードの前の数値は、元のバイナリ バイトコードへのオフセットです。

>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'

一部のバイトコードには、各バイトコードの動作に影響を与える追加情報 (引数) が付属しています。オフセットは、バイトストリーム内のどの位置でバイトコードが見つかったかを示します。

LOAD_CONSTバイトコード (ASCII 、hex 64)のd後には、バイトコードに関連付けられた定数への参照をエンコードする 2 つの追加バイトが続きます。その結果、STORE_FASTオペコード (ASCII }、hex 7D) はインデックス 3 で見つかります。

disモジュールのドキュメントには、各命令の意味が記載されています。についてLOAD_CONSTは、次のように述べています。

スタックにプッシュco_consts[consti]します。

co_constsコードオブジェクトに常に存在する構造を指します。コンパイラは次のように構成します。

>>> func.__code__.co_consts
(None, 1)

オペコードはその構造体からインデックス 1 をロードし (バイトコードの 01 00 バイトは 1 をエンコードします)、それdisを検索しました。それは値1です。

次の命令は、次のようにSTORE_FAST記述されます。

TOS をローカルに格納しco_varnames[var_num]ます。

ここで、 TOSはトップ オブ スタックを指します。値がスタックにプッシュLOAD_CONSTされたことに注意してください。別の構造です。ローカル変数名を参照し、オペコードはインデックス 0 を参照します。1co_varnames

>>> func.__code__.co_varnames
('x',)

disそれも調べました。コードで使用した名前は ですx。したがって、このオペコードは に格納さ1xます。

もう 1 つはインデックス 0 からスタックにLOAD_CONSTロードされ、その後に:NoneRETURN_VALUE

関数の呼び出し元に TOS で戻ります。

そのため、この命令は (定数と共に) スタックの一番上を取り、Noneこのコード ブロックから戻ります。明示的なステートメントNoneのない関数のデフォルトの戻り値です。return

dis出力、行番号から何かを省略しました:

>>> dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (x)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        

2最初の行に注意してください。これは、これらの手順に使用された Python コードを含む元のソースの行番号です。Python コード オブジェクトには、バイトコードを元のソースの行番号にマッピングできる属性がco_lnotabあります。逆アセンブリを表示するときにこれを行います。co_firstlinenodis

于 2013-10-24T08:03:16.397 に答える