Pythonで関数をdisする

**##加筆途中##**

#概要
Pythonでdisモジュールを用いて、関数の内部構造を確認する。

#目的
- Python3の内部動作を学ぶ準備として、関数の内部構造を確認する。

#環境
os: maxOS Sierra Version 10.12.6
python: Python 3.6.0

#内容
```Python3:インタープリタ
>>> 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`を定義した。

```Python3:インタープリタ
>>> def f(a, b):
...     c = len(a)
...     d = list(range(3))
...     a + b
...
```

##dis.disの実行
```Python3:インタープリタ
>>> 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の確認
```Python3
>>> 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行目
```Python
  2           0 LOAD_GLOBAL              0 (len)
```

（元ファイル`2`行目）（`0`バイト目の命令）`co_names[0]`つまり`'len'`という名前のグローバルをスタック上にロードする。
>LOAD_GLOBAL(namei)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loads the global named co_names[namei] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_names[namei] という名前のグローバルをスタック上にロードします。

###2行目
```Python
              2 LOAD_FAST                0 (a)
```
（`2`バイト目の命令）ローカルな`co_varnames[0]`つまり`'a'`への参照をスタックにプッシュする。
>LOAD_FAST(var_num)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pushes a reference to the local co_varnames[var_num] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ローカルな co_varnames[var_num] への参照をスタックにプッシュします。

###3行目
```Python
              4 CALL_FUNCTION            1
```
>CALL_FUNCTION(argc)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.
>
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changed in version 3.6: This opcode is used only for calls with positional arguments.


###4行目
```Python
              6 STORE_FAST               2 (c)
```
>STORE_FAST(var_num)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stores TOS into the local co_varnames[var_num].
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOS をローカルな co_varnames[var_num] の中に保存します。


###5行目
```Python
  3           8 LOAD_GLOBAL              1 (list)
```
>LOAD_GLOBAL(namei)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loads the global named co_names[namei] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_names[namei] という名前のグローバルをスタック上にロードします。


###6行目
```Python
             10 LOAD_GLOBAL              2 (range)
```
>LOAD_GLOBAL(namei)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loads the global named co_names[namei] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_names[namei] という名前のグローバルをスタック上にロードします。


###7行目
```Python
             12 LOAD_CONST               1 (3)
```

>LOAD_CONST(consti)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pushes co_consts[consti] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_consts[consti] をスタックにプッシュします。

###8行目
```Python
             14 CALL_FUNCTION            1
```
>CALL_FUNCTION(argc)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.
>
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changed in version 3.6: This opcode is used only for calls with positional arguments.

###9行目
```Python
             16 CALL_FUNCTION            1
```
>CALL_FUNCTION(argc)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.
>
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changed in version 3.6: This opcode is used only for calls with positional arguments.

###10行目
```Python
             18 STORE_FAST               3 (d)
```
>STORE_FAST(var_num)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stores TOS into the local co_varnames[var_num].
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOS をローカルな co_varnames[var_num] の中に保存します。

###11行目
```Python
  4          20 LOAD_FAST                0 (a)
```
>LOAD_FAST(var_num)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pushes a reference to the local co_varnames[var_num] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ローカルな co_varnames[var_num] への参照をスタックにプッシュします。

###12行目
```Python
             22 LOAD_FAST                1 (b)
```
>LOAD_FAST(var_num)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pushes a reference to the local co_varnames[var_num] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ローカルな co_varnames[var_num] への参照をスタックにプッシュします。

###13行目
```Python
             24 BINARY_ADD
```
>BINARY_ADD
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implements TOS = TOS1 + TOS.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOS = TOS1 + TOS を実行します。


###14行目
```Python
             26 POP_TOP
```
>POP_TOP
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes the top-of-stack (TOS) item.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;スタックの先頭 (TOS) の要素を取り除きます。

###15行目
```Python
             28 LOAD_CONST               0 (None)
```
>LOAD_CONST(consti)
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pushes co_consts[consti] onto the stack.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_consts[consti] をスタックにプッシュします。


###4行目
```Python
             30 RETURN_VALUE
```
>RETURN_VALUE
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns with TOS to the caller of the function.
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;関数の呼び出し元へ 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)