Slide 1

Slide 1 text

Pythonの処理系はどのように実装され,どのよう に動いているのか? 我々はその実態を調査すべ くアマゾンへと飛んだ. KMC春合宿2017 @utgwkk

Slide 2

Slide 2 text

私について ● @utgwkk ● KMC-ID: utgw ● 京都大学工学部情報学科 計算機科学コース2回生 ● デレステ: 581948763

Slide 3

Slide 3 text

講座の対象・予定 ● C言語のような静的型付け・コンパイル言語しか触ったことがない人向け ● 動的型付け・インタプリタ言語の中身が気になる人向け ● Python の標準実装である CPython がどう実装されているのか見ていく ○ 他の実装もだいたいこんな感じ? ● あまり深いところまで行かずにざっと見ていく予定 ○ 私の理解が追い付いていないので

Slide 4

Slide 4 text

今日話すこと 1. Python の概要 2. Python のオブジェクトの構造体による内部表現 3. Python の主要なデータ型の実装 4. Python の関数・モジュールの実装 5. Python のコードの実行・仮想機械について

Slide 5

Slide 5 text

1. Python の概要 2. Python のオブジェクトの構造体による内部表現 3. Python の主要なデータ型の実装 4. Python の関数・モジュールの実装 5. Python のコードの実行・仮想機械について どのように実装され 今日話すこと どのように動いているのか

Slide 6

Slide 6 text

Python の概要

Slide 7

Slide 7 text

Python とは ● Guido van Rossum が作ったプログラミング言語 ● 動的型付けプログラミング言語 ● インタプリタ言語 ● 最新バージョンは 3.6 (2016/12/23)

Slide 8

Slide 8 text

Python の特徴 ● 動的型付けプログラミング言語である ○ 型ヒントが最近導入された ● インタプリタ言語である ● インデントによってブロックを表現する (オフサイドルール) ● コードがシンプルで扱いやすく設計されている ● 機械学習・統計ライブラリが豊富 ○ 日本だと機械学習目的で書いてる人が多そう [要出典]

Slide 9

Slide 9 text

Python のコードの例 ● 変数の定義 x = 12345 # int(整数型) st = “this is string” # str(文字列型) bo = True # bool(真偽値) obj = None # 何もない的な

Slide 10

Slide 10 text

Python のコードの例 ● 変数の定義 alist = [3, 4, 6] atuple = (3, 4, 6) adict = {‘hoge’: 10, ‘fuga: 20} aset = {1, 3, 5, 7}

Slide 11

Slide 11 text

Python のコードの例 ● 関数の定義 (def 文) def process(x, y=5): return x + y - 1

Slide 12

Slide 12 text

Python のコードの例 ● 条件分岐 (if 文) if num < 50: print(“less than 50.”) elif num < 100: print(“less than 100.”) else: print(“sugo-i!!!!!!!”)

Slide 13

Slide 13 text

Python のコードの例 ● 繰り返し (for 文,while 文) for i in range(10): print(i ** 2) while i < 50: i *= 2

Slide 14

Slide 14 text

Python のコードの例 ● 例外処理 try: do_something_abunai() except NanikaError as e: print(‘例外が発生し,捕捉される場合’) else: print(‘例外が発生しなかった場合’) finally: print(‘いずれの場合にも実行される処理’)

Slide 15

Slide 15 text

Python のコードの例 ● コンテキストマネージャ ○ あるオブジェクトに対する初期化と後片付けをまとめて記述できる ■ Go の defer,C# の using 文と似ている ○ open() されたファイルは with 文を抜ける際に必ず close() される with open(“hoge.txt”, “wt”) as f: f.write(data)

Slide 16

Slide 16 text

Python のコードの例 ● コンテキストマネージャ ○ だいたいこのコードと等価 f = open(“hoge.txt”, “wt”) try: f.write(data) finally: f.close()

Slide 17

Slide 17 text

Python のコードの例 ● ジェネレータ ○ なんらかの処理をした値を複数回返すというときに便利 ○ 遅延評価イテレータを簡単に作れる def gen(): data = do_something() yield data yield do_something_else(data)

Slide 18

Slide 18 text

Python のコードの例 ● 値のスワップ ○ これでいい ○ 一時変数は使わないの? ■ あとで見る x, y = y, x

Slide 19

Slide 19 text

Python のコードの例 ● 内包表記 [x ** 2 for x in range(100) if x % 2 == 0] {x ** 2 for x in range(100) if x % 2 == 0} {str(x): x for x in range(100) if x % 2 == 0} (x ** 2 for x in range(100) if x % 2 == 0) # ジェネレータ

Slide 20

Slide 20 text

Python のオブジェクトの構造体によ る内部表現

Slide 21

Slide 21 text

CPython ● van Rossum が書いた Python の標準実装 ● C言語で記述されている ● CPython を使ってライブラリを書くことができる ○ いわゆるC拡張ですね

Slide 22

Slide 22 text

Python のオブジェクトの実装 ● オブジェクトを表す構造体 ○ PyObject ○ PyVarObject ● クラスを表す構造体 ○ PyTypeObject

Slide 23

Slide 23 text

オブジェクトを表す2つの構造体 typedef struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; struct _typeobject *ob_type; } PyObject; typedef struct { PyObject ob_base; Py_ssize_t ob_size; } PyVarObject; #define _PyObject_HEAD_EXTRA Includes/object.h L106-115 PyVarObject extends PyObject

Slide 24

Slide 24 text

Py(Var)Object の持つ要素 ● オブジェクトの参照カウンタ (ob_refcnt) ● PyTypeObject へのポインタ (*ob_type) ● (可変長オブジェクトの要素数 (ob_size) )

Slide 25

Slide 25 text

PyTypeObject ● Doc/includes/typestruct.h ● Python のクラスを表す構造体 ● メンバがいっぱいある ○ 演算子オーバーロードとか ○ メンバ関数,メンバ変数 ○ ハッシュ関数

Slide 26

Slide 26 text

関係性 PyObject PyVarObject PyTypeObject

Slide 27

Slide 27 text

この他にもいろいろな構造体があります ● おいおい出てくるのでその都度やっていきます ○ データ構造を表す構造体 ○ メンバ関数を表す構造体 ○ モジュールを表す構造体 ○ etc.

Slide 28

Slide 28 text

Python の主要なデータ型の実装

Slide 29

Slide 29 text

Python のデータ型 ● 組み込みデータ型 ○ int (整数), float (浮動小数点数) ○ str (文字列), bytes (バイナリ列) ○ コンテナ ○ 他にもあるけどとりあえずこれぐらい

Slide 30

Slide 30 text

Python のデータ型 ● 組み込みデータ型 ○ int (整数), float (浮動小数点数) ○ str (文字列), bytes (バイナリ列) ○ コンテナ ○ 他にもあるけどとりあえずこれぐらい

Slide 31

Slide 31 text

int: struct _longobject ● 多倍長整数 ○ (メモリの許す限り)いくらでも大きな整数を表すことができる struct _longobject { PyVarObject ob_base; digit ob_digit[1]; }; ob_digit[0] ob_digit[1] ob_digit[2] ... ob_digit[ob_size - 1]

Slide 32

Slide 32 text

int: struct _longobject ● 負の数は ob_size を負にすることで表している ● 0 のときは ob_size == 0 ● ある整数Xの絶対値に対して,次の関係が成り立つ ○ D i は ob_digit[i] ○ N は ob_size の絶対値 ○ S はシフト数 (15 もしくは 30)

Slide 33

Slide 33 text

多倍長整数の足し算・引き算 ● 多倍長整数の足し算・引き算は,筆算に似た方法で行われる ob_digit[0] ob_digit[1] ob_digit[2] ... ob_digit[ob_size - 1] ob_digit[0] ob_digit[1] ob_digit[2] ... ob_digit[ob_size - 1] ob_digit[0] ob_digit[1] ob_digit[2] ... ob_digit[ob_size - 1] A B A+B carry carry carry add add add add

Slide 34

Slide 34 text

多倍長整数の掛け算・割り算 ● 多倍長整数の掛け算・割り算はちょっと複雑で説明しきれないので省略 ○ 愚直にやると遅いので,最適化されたアルゴリズムが用いられている ○ 次のワードでググろう ■ カラツバ法 ○ 次の書籍をあたろう ■ The Art of Computer Programming (D. Knuth) ■ Handbook of Applied Cryptography (Alfred J. Menezes ほか)

Slide 35

Slide 35 text

Python のコンテナ ● 次の4つを取り上げます ○ list ○ collections.deque ○ dict ○ set ● CPython では各種操作の時間計算量が規定されている ○ https://wiki.python.org/moin/TimeComplexity

Slide 36

Slide 36 text

list: PyListObject ● list という名前をしているけど,動的配列 typedef struct { PyObject_VAR_HEAD // PyVarObject としての情報 PyObject **ob_item; // 要素へのポインタ Py_ssize_t allocated; // 確保しているサイズ(≠要素数) } PyListObject; [0] [1] [2] [ob_size - 1] ... ... allocated

Slide 37

Slide 37 text

collections.deque ● 双方向連結リストによって実装された両端キュー ● 先頭への要素の追加がO(1)でできる ● 要素のローテート(Piet でいうところの roll)ができる

Slide 38

Slide 38 text

dict: PyDictObject ● ハッシュテーブル typedef struct { PyObject_VAR_HEAD Py_ssize_t ma_used; // 辞書の要素数 uint64_t ma_version_tag; // 辞書のバージョン PyDictKeysObject *ma_keys; // 辞書のキーのリスト PyObject **ma_values; // 辞書の値を格納するテーブル } PyDictObject;

Slide 39

Slide 39 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2

Slide 40

Slide 40 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 hoge

Slide 41

Slide 41 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 hoge 0

Slide 42

Slide 42 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 hoge 0

Slide 43

Slide 43 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 hoge 0

Slide 44

Slide 44 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 fuga value_2

Slide 45

Slide 45 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 fuga value_2

Slide 46

Slide 46 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 fuga value_2 1 fuga value_2

Slide 47

Slide 47 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 piyo value_3 fuga value_2

Slide 48

Slide 48 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 piyo value_3 fuga value_2

Slide 49

Slide 49 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 piyo value_3 fuga value_2

Slide 50

Slide 50 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 piyo value_3 fuga value_2

Slide 51

Slide 51 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 piyo value_3 fuga value_2 2

Slide 52

Slide 52 text

dict: PyDictObject ● ハッシュテーブル hoge value_1 0 1 2 1 piyo value_3 fuga value_2 2 piyo value_3

Slide 53

Slide 53 text

set ● (要素の重複を許さない)集合 ● 実装はほとんど dict と同じなので省略 ○ dict に key だけを格納するとだいたい set になる

Slide 54

Slide 54 text

Python の関数/モジュールの実装

Slide 55

Slide 55 text

モジュールの作り方 ● だいたい以下の手順を踏めば CPython でライブラリが作れます ● クラスや定数を意図的に無視しています 1. 関数を書く 2. 関数の一覧を登録する 3. モジュールの情報を登録する 4. モジュールの初期化をする関数を書く

Slide 56

Slide 56 text

関数を書く ● 関数は static で宣言する ● 引数は (PyObject*, PyObject*) とする ● 返り値も PyObject* とする ● がんばる

Slide 57

Slide 57 text

関数を書く (具体的に) ● 関数は static で宣言する ○ 外部から見えていい関数は,後述する「モジュールを初期化する関数」のみとする ● 引数は (PyObject*, PyObject*) とする ○ 1つ目はモジュール自身を表す (だいたい self と名付ける) ○ 2つ目は引数を格納した Python のタプル (だいたい args と名付ける) ○ これを PyArg_ParseTuple() 関数を使ってパースすると,所望の値が得られる ● 返り値も PyObject* とする ○ None を返すときは Py_RETURN_NONE マクロを使う

Slide 58

Slide 58 text

関数を書く (具体的に) ● がんばる ○ あとはC言語で書くだけ!!!!!!!! ○ 手動で参照カウントを増減させる ■ このへんは Cython とか使うともっと楽に書けると思う ■ 今回はそこまで踏み込みません

Slide 59

Slide 59 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} }

Slide 60

Slide 60 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} } 関数の名前

Slide 61

Slide 61 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} } 関数ポインタ (PyCFunction にキャストする)

Slide 62

Slide 62 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} } 引数の受け取り方

Slide 63

Slide 63 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} } 関数の説明文

Slide 64

Slide 64 text

関数の一覧を登録する ● PyMethodDef の配列に詰め込む ● 終端に番兵を置く static PyMethodDef mysortmethods[] = { {“bubblesort”, (PyCFunction)bubblesort, METH_VARARGS, “bubblesort.”}, {NULL, NULL, 0, NULL} } 番兵(終端を表す)

Slide 65

Slide 65 text

モジュールの情報を登録する ● PyModuleDef 構造体 ○ モジュールの名前 ○ モジュールの説明 ○ モジュールが利用するメモリ領域の大きさ ○ モジュールの関数・クラス

Slide 66

Slide 66 text

モジュールの初期化をする関数を書く ● これだけ非 static で宣言する ● これで import できるようになる

Slide 67

Slide 67 text

実例を見る ● バブルソート関数だけがある mysort というモジュールを書いた ○ https://github.com/utgwkk/python-c-api-practice ● setup.py をよしなに書くとモジュールとして配布できる ● 組み込みライブラリの場合は CPython のビルド時によしなにされる ● TODO: コードをざっと見る ● TODO: インストールできることを確認する

Slide 68

Slide 68 text

Python のコードの実行・仮想機械 について

Slide 69

Slide 69 text

よくあるコンパイル言語の実行手順 コードを構文解析する 抽象構文木に変換する 実行する 実行可能バイナリを生成する

Slide 70

Slide 70 text

素朴なインタプリタ言語の実行手順 コードを構文解析する 抽象構文木に変換する 評価する

Slide 71

Slide 71 text

Python の実行手順 コードを構文解析する 抽象構文木に変換する 仮想機械で評価する 仮想機械用のバイトコードに変換する

Slide 72

Slide 72 text

実行の手順 (PEP 339 より) 1. コードを解析して解析木にする 2. 解析木を抽象構文木(AST)に変換する 3. 抽象構文木を制御フローグラフ(CFG)に変換する 4. 制御フローグラフを基にしてバイトコードを生成する 5. バイトコードを仮想機械上で実行する

Slide 73

Slide 73 text

実行の手順 (PEP 339 より) 1. コードを解析して解析木にする 2. 解析木を抽象構文木(AST)に変換する 3. 抽象構文木を制御フローグラフ(CFG)に変換する 4. 制御フローグラフを基にしてバイトコードを生成する 5. バイトコードを仮想機械上で実行する

Slide 74

Slide 74 text

バイトコードへの変換 ● Python のコードは最終的にバイトコード(中間コード)にコンパイルされる ○ 1バイトで命令を表す(256通り) ○ これと引数を組み合わせて 2バイトが命令の最小単位 ● コンパイルされたバイトコードは仮想機械(VM)上で実行される ● こういうタイプのインタプリタをバイトコードインタプリタと呼ぶ

Slide 75

Slide 75 text

なぜ「コンパイル」? ● 高級なコードを低級な命令(バイトコード)に変換してから 仮想機械上で実行したほうが速い ● いろんな言語がこういう体系を取っている ○ Java, C#, Ruby, ...

Slide 76

Slide 76 text

PyCodeObject (Include/code.h) ● バイトコードを表す構造体 ○ 引数の数 ○ スタックの大きさ ○ 命令コード ○ ローカル変数の配列 ○ 定数の配列

Slide 77

Slide 77 text

バイトコードを逆アセンブルする ● TODO: 「Python のコードの例」で紹介したコードのバイトコードを見る ○ 条件分岐 ○ 制御構造 ○ 例外処理 ○ コンテキストマネージャ ○ ジェネレータ ● TODO:見る ○ x, y = y, x

Slide 78

Slide 78 text

Python VM の仕様 ● スタックマシン ○ データのやりとりにスタックを用いる ○ 計算対象としてスタックのトップから順に数えていく ● 命令一覧 ○ http://docs.python.jp/3/library/dis.html#python-bytecode-instructions

Slide 79

Slide 79 text

Python VM の正体 ● PyFrameObject 構造体がその正体 ○ PyCodeObject へのポインタ(バイトコードの列) ○ グローバル変数,ローカル変数などへのポインタ ○ スタック ○ 例外オブジェクト,トレースバックの情報 ● 関数呼び出しごとに作られる ○ ジェネレータが簡単に実現できる

Slide 80

Slide 80 text

_PyEval_EvalFrameDefault() 関数 ● ここに PyFrameObject を渡して PyCodeObject を実行している ● 終了条件に達するまでバイトコードを順に実行する ○ 無限ループ (for (;;)) の中がその実体 ○ 終了条件 ■ return 文が実行される ■ 例外が送出され try~except で捕捉されない

Slide 81

Slide 81 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a print

Slide 82

Slide 82 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a print

Slide 83

Slide 83 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a print 6

Slide 84

Slide 84 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a print 6

Slide 85

Slide 85 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print 6

Slide 86

Slide 86 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 87

Slide 87 text

print シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 88

Slide 88 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print print a

Slide 89

Slide 89 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print print a

Slide 90

Slide 90 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print print a

Slide 91

Slide 91 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 92

Slide 92 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print None

Slide 93

Slide 93 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print None

Slide 94

Slide 94 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print None

Slide 95

Slide 95 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 96

Slide 96 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 97

Slide 97 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print None

Slide 98

Slide 98 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print None

Slide 99

Slide 99 text

シミュレートしてみよう 1 0 LOAD_CONST 3 (6) 2 STORE_NAME 0 (a) 4 LOAD_NAME 1 (print) 6 LOAD_NAME 0 (a) 8 CALL_FUNCTION 1 10 POP_TOP 12 LOAD_CONST 2 (None) 14 RETURN_VALUE 定数: None 6 名前: a = 6 print

Slide 100

Slide 100 text

まとめ

Slide 101

Slide 101 text

まとめ ● Python のオブジェクトはいろいろな構造体で表現されている ● Python のコードは最適化を経てバイトコードにコンパイルされる ● Python のコンパイルされたバイトコードは VM 上で実行される ● 質問は分かる範囲で答えます

Slide 102

Slide 102 text

参考 ● Inside The Python Virtual Machine https://leanpub.com/insidethepythonvirtualmachine/read ● About Python VM http://svn.coderepos.org/share/docs/jbking/vmdoc/about_python_vm.html ● CPython の Git リポジトリ https://github.com/python/cpython ● Python 3.6.0 Documentation http://docs.python.jp/3/