##加筆途中##
#概要
Pythonでdisモジュールを用いて、関数の内部構造を確認する。
#目的
- Python3の内部動作を学ぶ準備として、関数の内部構造を確認する。
#環境
os: maxOS Sierra Version 10.12.6
python: Python 3.6.0
#内容
>>> def f(a, b):
... c = len(a)
... d = list(range(3))
... a + b
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 STORE_FAST 2 (c)
3 8 LOAD_GLOBAL 1 (list)
10 LOAD_GLOBAL 2 (range)
12 LOAD_CONST 1 (3)
14 CALL_FUNCTION 1
16 CALL_FUNCTION 1
18 STORE_FAST 3 (d)
4 20 LOAD_FAST 0 (a)
22 LOAD_FAST 1 (b)
24 BINARY_ADD
26 POP_TOP
28 LOAD_CONST 0 (None)
30 RETURN_VALUE
#詳細
##disする関数の定義
以下のように、(深い意味はない)関数f
を定義した。
>>> def f(a, b):
... c = len(a)
... d = list(range(3))
... a + b
...
##dis.disの実行
>>> import dis
>>> dis.dis(f)
2 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 STORE_FAST 2 (c)
3 8 LOAD_GLOBAL 1 (list)
10 LOAD_GLOBAL 2 (range)
12 LOAD_CONST 1 (3)
14 CALL_FUNCTION 1
16 CALL_FUNCTION 1
18 STORE_FAST 3 (d)
4 20 LOAD_FAST 0 (a)
22 LOAD_FAST 1 (b)
24 BINARY_ADD
26 POP_TOP
28 LOAD_CONST 0 (None)
30 RETURN_VALUE
1列目は元のファイルでの行数を、2列目は何バイト目のコードであるかを、3列目は人間が読むための命令名を、
各バイトコード命令の確認
###co_varnames, co_names, co_constsの確認
>>> for attr in ('co_varnames', 'co_names', 'co_consts'):
... print('{0}:\t{1}'.format(attr, getattr(f.__code__, attr)))
...
co_varnames: ('a', 'b', 'c', 'd')
co_names: ('len', 'list', 'range')
co_consts: (None, 3)
予めco_varnames, co_names, co_constsを確認しておいた
###1行目
2 0 LOAD_GLOBAL 0 (len)
(元ファイル2
行目)(0
バイト目の命令)co_names[0]
つまり'len'
という名前のグローバルをスタック上にロードする。
LOAD_GLOBAL(namei)
Loads the global named co_names[namei] onto the stack.
co_names[namei] という名前のグローバルをスタック上にロードします。
###2行目
2 LOAD_FAST 0 (a)
(2
バイト目の命令)ローカルなco_varnames[0]
つまり'a'
への参照をスタックにプッシュする。
LOAD_FAST(var_num)
Pushes a reference to the local co_varnames[var_num] onto the stack.
ローカルな co_varnames[var_num] への参照をスタックにプッシュします。
###3行目
4 CALL_FUNCTION 1
CALL_FUNCTION(argc)
Calls a function. argc indicates the number of positional arguments. The positional arguments are on the stack, with the right-most argument on top. Below the arguments, the function object to call is on the stack. Pops all function arguments, and the function itself off the stack, and pushes the return value.Changed in version 3.6: This opcode is used only for calls with positional arguments.
###4行目
6 STORE_FAST 2 (c)
STORE_FAST(var_num)
Stores TOS into the local co_varnames[var_num].
TOS をローカルな co_varnames[var_num] の中に保存します。
###5行目
3 8 LOAD_GLOBAL 1 (list)
LOAD_GLOBAL(namei)
Loads the global named co_names[namei] onto the stack.
co_names[namei] という名前のグローバルをスタック上にロードします。
###6行目
10 LOAD_GLOBAL 2 (range)
LOAD_GLOBAL(namei)
Loads the global named co_names[namei] onto the stack.
co_names[namei] という名前のグローバルをスタック上にロードします。
###7行目
12 LOAD_CONST 1 (3)
LOAD_CONST(consti)
Pushes co_consts[consti] onto the stack.
co_consts[consti] をスタックにプッシュします。
###8行目
14 CALL_FUNCTION 1
CALL_FUNCTION(argc)
Calls a function. argc indicates the number of positional arguments. The positional arguments are on the stack, with the right-most argument on top. Below the arguments, the function object to call is on the stack. Pops all function arguments, and the function itself off the stack, and pushes the return value.Changed in version 3.6: This opcode is used only for calls with positional arguments.
###9行目
16 CALL_FUNCTION 1
CALL_FUNCTION(argc)
Calls a function. argc indicates the number of positional arguments. The positional arguments are on the stack, with the right-most argument on top. Below the arguments, the function object to call is on the stack. Pops all function arguments, and the function itself off the stack, and pushes the return value.Changed in version 3.6: This opcode is used only for calls with positional arguments.
###10行目
18 STORE_FAST 3 (d)
STORE_FAST(var_num)
Stores TOS into the local co_varnames[var_num].
TOS をローカルな co_varnames[var_num] の中に保存します。
###11行目
4 20 LOAD_FAST 0 (a)
LOAD_FAST(var_num)
Pushes a reference to the local co_varnames[var_num] onto the stack.
ローカルな co_varnames[var_num] への参照をスタックにプッシュします。
###12行目
22 LOAD_FAST 1 (b)
LOAD_FAST(var_num)
Pushes a reference to the local co_varnames[var_num] onto the stack.
ローカルな co_varnames[var_num] への参照をスタックにプッシュします。
###13行目
24 BINARY_ADD
BINARY_ADD
Implements TOS = TOS1 + TOS.
TOS = TOS1 + TOS を実行します。
###14行目
26 POP_TOP
POP_TOP
Removes the top-of-stack (TOS) item.
スタックの先頭 (TOS) の要素を取り除きます。
###15行目
28 LOAD_CONST 0 (None)
LOAD_CONST(consti)
Pushes co_consts[consti] onto the stack.
co_consts[consti] をスタックにプッシュします。
###4行目
30 RETURN_VALUE
RETURN_VALUE
Returns with TOS to the caller of the function.
関数の呼び出し元へ TOS を返します。
#意義
#疑問
どうしてTOSの説明が日本語訳では書いていないのであろうか。
#参考文献
[1] 32.12. dis — Disassembler for Python bytecode (https://docs.python.org/3/library/dis.html)
[2] 32.12. dis — Python バイトコードの逆アセンブラ (https://docs.python.org/ja/3/library/dis.html)