タイトル
27 評価ループ
28 フレーム
29 スタックベースの実行
30 バイトコードの説明
31 関数呼び出し
32 メソッド呼び出し
33 属性の検索
34 例外処理
35 発電機
36 コルーチンと非同期
37 パターンマッチング
38 内包表記
39 クロージャとセル
  • 27. 評価ループ

    #27. 評価ループ 評価ループは、CPython の中心的な実行エンジンです。コンパイルされたコード オブジェクトを取得し、そのバイトコード命令を実行して、結果または例外を生成します。 大まかに言うと、CPython の実行は次のようになります。```text Python source ↓ tokens ↓ parser ↓ AST ↓ symbol table ↓ compiler ↓ code object ↓ frame ↓ evaluation loop ↓ Python result or exception 評価ループは CPython のインタプリタ実装内に存在します。歴史的に、キー ファイルは ` Python / ceval . c ` 、周囲のインタプリタ機構が他のファイルに分散されています。最新の CPython は、バイトコード定義からいくつかのインタープリター コードも生成します。詳細はリリース間で変化しますが、モデルは安定しています。フレームはバイトコード命令を繰り返しディスパッチすることでコード オブジェクトを実行します。このコードはバージョン間で変更されるため、 CPython 独自の開発者ガイドでは、現在の参照として内部ドキュメントとソース ツリーを示しています。 ## 27.1 評価ループの仕事 評価ループは Python テキストを解析しません。 AST は構築されません。通常、語彙の範囲は決定されません。これらのジョブは、実行が開始されるまでにすでに終了しています。 その仕事はより狭く、より機械的です。 ``` text read the next bytecode instruction decode its…

  • 28. フレーム

    #28. フレーム フレームは、Python コードの 1 回のアクティブな実行の実行時レコードです。 CPython は、Python 関数の呼び出し、モジュール本体の実行、クラス本体の実行、ジェネレーターの再開、またはコルーチンの再開を行うときに、フレームのような実行レコードを使用して現在の状態を保持します。 コード オブジェクトは、何を実行するかを示します。 フレームには、現在どこで実行されているか、および現在どのような値が生きているかが示されます。 text code object = immutable instructions and metadata frame = mutable execution state for one run of that code この関数の場合:```python def add(a, b): c = a + b return c のために作られたフレーム ` add ( 2 , 3 ) ` 現在の引数値、ローカル変数スロット、スタック値、命令位置、例外状態、および実行コンテキストへのリンクが含まれます。 ## 28.1 フレームが存在する理由 Python プログラムでは、同時に多数のアクティブな呼び出しを行うことができます。 ``` python def a (): return b () def b (): return c…

  • 29. スタックベースの実行

    #29. スタックベースの実行 CPython は、ほとんどのバイトコードをスタック マシンで実行します。スタック マシンは、すべての命令でソース レジスタとデスティネーション レジスタを明示的に指定するのではなく、暗黙的なオペランド スタックを使用します。 CPython では、このスタックは現在のフレームに属します。 Python オブジェクトへの参照を保存します。バイトコード命令は、オブジェクトのプッシュ、オブジェクトのポップ、オブジェクトの検査、オブジェクトの置換、およびオブジェクトを使用した新しい結果の計算を行います。 簡単な表現: python id="kz6m7x" x = a + b 概念的には次のように実行されます。 text id="eurdpx" LOAD_FAST a push a LOAD_FAST b push b BINARY_OP + pop b and a, push result STORE_FAST x pop result into local x 命令ストリームには次のような記述はありません。 text id="ardj57" add local_a, local_b, local_x 代わりに、次のように書かれています。```text id="jzzlmf" load a load b add top two stack values store result ## 29.1 CPython…

  • 30. バイトコード命令

    #30. バイトコード命令 バイトコード命令は、CPython 評価ループによって実行される操作です。これらは、解析、AST 構築、シンボル分析、コンパイル後の Python コードのコンパクトなインタープリター レベルの形式です。 次のような Python 関数:```python id="ya54lv" def add(a, b): return a + b そのストリームを検査するには、 ` dis ` : ``` python id = "7yf46p" import dis def add ( a , b ): return a + b dis . dis ( add ) ``` 出力は Python のバージョンによって異なりますが、通常は次のような指示が表示されます。 ``` text id = "ot1vx4" LOAD_FAST LOAD_FAST BINARY_OP RETURN_VALUE ``` これらの命令は CPython 仮想マシンの語彙です。 ## 30.1 バイトコード命令とは バイトコード命令は、インタプリタに 1…

  • 31. 関数呼び出し

    #31. 関数呼び出し 関数呼び出しは、CPython の最も重要な実行パスの 1 つです。呼び出しは、バイトコードの実行、フレーム、引数バインディング、記述子、メソッド、クロージャ、C API、参照カウント、例外、戻り処理などの複数のシステムを同時に接続します。 簡単な呼び出し: python id="wauh11" result = f(1, 2) ソースレベルでは小さく見えます。実行時、CPython は次のことを行う必要があります。```text id="rhdr0d" load the callable load the arguments choose the correct call protocol bind arguments to parameters create or initialize a frame if calling Python code execute the callee return a result or propagate an exception store the result ## 31.1 通話の意味 Python では、呼び出し式は次の一般的な形式になります。 ``` python id = "a7ltua" callable_object ( arguments ) ``` 括弧の前のオブジェクトは呼び出し可能である必要があります。…

  • 32. メソッド呼び出し

    #32. メソッド呼び出し メソッド呼び出しは、通常は属性アクセスで始まる関数呼び出しです。ほとんどのオブジェクトの動作はメソッドを通じて公開されるため、これらは Python のオブジェクト モデルの中心となります。 次のようなメソッド呼び出し: python id="l3owku" obj.method(arg) 1 つの操作のように見えますが、CPython はいくつかの概念的なステップを実行します。```text id="j39rdj" load obj look up attribute method bind obj if needed load arg call the resolved callable return result or raise exception ## 32.1 メソッド呼び出しは属性アクセスと呼び出しである ソース式 : ``` python id = "xgyvgk" obj . method ( 10 ) ``` は次のように理解できます。 ``` python id = "gg912h" tmp = obj . method tmp ( 10 ) ``` これは正しいセマンティック モデルです。属性の検索が最初に行われます。その後、その検索の結果が呼び出されます。…

  • 33. 属性の検索

    #33. 属性の検索 属性検索は、次のような式を評価するために使用されるランタイム プロセスです。```python id="5ob0m9" obj.name 単純な属性式が大量の機械をトリガーする可能性があります。 ``` text id = "b2zmcv" find the object 's type search the type and its base classes handle descriptors check the instance dictionary call custom attribute hooks return a value or raise AttributeError ```属性の検索は動的です。結果は、ランタイム オブジェクト、そのクラス、その基本クラス、そのインスタンス ディクショナリ、記述子、メタクラス、およびユーザー定義のフックによって異なります。 ## 33.1 基本的な属性アクセス 式:```python id="67bubm" obj.x ```CPython に、という名前の属性を検索するよう依頼します。`"x"`の上`obj`。 見つかった場合、ルックアップは Python オブジェクトを返します。 欠落している場合は値が上がります`AttributeError`。 例:```python id="l53g0p" class C: pass obj = C() obj.x = 10 print(obj.x) ```割り当てストア`x`インスタンス辞書内:```text id="kz7fxs" obj.__dict__["x"]…

  • 34. 例外処理

    #34. 例外処理 例外処理は、操作が正常に完了できない場合に CPython が使用する制御フロー システムです。露骨な内容もカバーします raise ステートメント、失敗した操作、失敗したインポート、失敗した呼び出し、ジェネレーターの終了、コンテキスト マネージャーのクリーンアップ、トレースバックの構築、およびフレームを介した伝播。 ソースレベルでは、例外は次のようになります。 python id="cq34p8" try: value = risky() except ValueError: value = 0 実行時、CPython は次のことを行う必要があります。```text id="o1a48o" execute the protected bytecode range detect failure record the active exception find a matching handler restore the frame stack to a valid state jump to handler bytecode run cleanup code propagate if no handler matches ## 34.1 例外とは何か 例外は、異常な制御フローを表すオブジェクトです。 ほとんどの例外は、から派生したクラスのインスタンスです。 ` BaseException ` 。 ``` python…

  • 35. 発電機

    #35. 発電機 ジェネレーターは再開可能な関数です。通常の関数は、開始、実行、および 1 つの戻り値で終了します。ジェネレーターは、開始して値を生成し、フレームを一時停止し、後で同じ命令位置から再開して別の値を生成し、終了するまで繰り返すことができます。 ジェネレーター関数は、以下を含む関数本体です。 yield 。 python id="j7t4va" def numbers(): yield 1 yield 2 yield 3 この関数を呼び出しても、本体はすぐには実行されません。 python id="oyb9ik" g = numbers() この呼び出しによりジェネレーター オブジェクトが作成されます。ジェネレーターが再開されると本体が開始されます。 python id="9sgmxp" print(next(g)) print(next(g)) print(next(g)) 出力: text id="wj3i3f" 1 2 3 最後の値の後、次の再開で値が発生します StopIteration 。 35.1 ジェネレータ関数とジェネレータ オブジェクト ジェネレーター関数は、次のように定義された呼び出し可能関数です。 def 。 ジェネレーター オブジェクトは、ジェネレーター関数が呼び出されたときに返される再開可能なイテレーターです。```python id="nckwxg" def gen(): yield 1 print(gen) print(gen()) 概念的には: text id="hfh6hz" gen function object gen() generator object suspended execution state code object frame…

  • 36. コルーチンと非同期

    #36. コルーチンと非同期 コルーチンは、非同期プログラミングに使用される再開可能な計算です。 Python コードを一時停止させます。 await ポイントに戻り、制御をイベント ループに戻し、後で待機中の操作の結果が得られたときに再開します。 コルーチンはジェネレーターと似ており、どちらも一時停止後も実行状態を保持します。違いはプロトコルと目的です。 ジェネレーターはイテレーター・コンシューマーに値を生成します。 コルーチンは他の非同期操作を待機し、最終的に 1 つの最終結果を返します。 python id="o2u8bi" async def fetch(): data = await read() return data 電話をかける fetch() 本体を最後まで実行しません。コルーチンオブジェクトを作成します。```python id="9i5ai1" coro = fetch() ## 36.1 コルーチン関数とコルーチン オブジェクト アン ` async def ` ステートメントはコルーチン関数を作成します。 コルーチン関数を呼び出すと、コルーチン オブジェクトが作成されます。 ``` python id = "rt8ky9" async def work (): return 42 coro = work () ``` 概念的には : ``` text id = "q71j65" work coroutine function object…

  • 37. パターンマッチング

    #37. パターンマッチング パターン マッチングは Python の構造マッチング システムです。それを実装するのは、 match 声明と case 条項。```python match value: case 0: result = "zero" case [x, y]: result = x + y case {"name": name}: result = name case _: result = None CPython レベルでは、パターン マッチングは通常のバイトコードと特殊なマッチング命令にコンパイルされます。インタプリタはサブジェクトを評価し、各ケースを順番に試し、一致が成功した場合に名前をバインドし、選択された本文にジャンプします。 ## 37.1`match`声明 あ ` match ` ステートメントには 1 つの主語式と 1 つ以上のケースがあります。 ``` python match subject : case pattern : body case pattern if guard : body case _ : body…

  • 38. 内包表記

    #38. 内包表記 内包表記は、別の反復可能オブジェクトからコンテナーまたはジェネレーターのような反復子を構築するためのコンパクトな構文です。 CPython は、それらを独自の実行スコープを持つコンパイル済みコード オブジェクトとして実装します。 一般的な形式: python [x * 2 for x in xs] {x * 2 for x in xs} {x: x * 2 for x in xs} (x * 2 for x in xs) これらは以下に対応します。```text list comprehension set comprehension dict comprehension generator expression ## 38.1 リストの内包表記 リスト内包では、熱心にリストを構築します。 ``` python ys = [ x * 2 for x in xs ] ``` 概念的には : ``` python ys =…

  • 39. クロージャとセル

    #39. クロージャとセル クロージャを使用すると、入れ子になった関数は、囲んでいる関数が返された後、その関数からの変数を使用できます。```python def make_adder(n): def add(x): return x + n return add add10 = make_adder(10) print(add10(5)) 出力: text 15 ```変数 n に属します make_adder 、 しかし add 後でもそれを使用します。 CPython は、キャプチャされた変数をセル オブジェクトに移動することでこれをサポートします。内部関数はそれらのセルへの参照を保持します。 39.1 入れ子関数 ネストされた関数は、別の関数の内部で定義された関数です。```python def outer(): def inner(): return 1 return inner ```の def inner ステートメントが実行されるタイミング outer 走る。関数オブジェクトを作成し、それをローカル名にバインドします。 inner 。 電話をかける outer() その関数オブジェクトを返します。 python fn = outer() print(fn()) の関数オブジェクト inner 含まれるもの: text code object globals dictionary defaults keyword defaults annotations…