8. 複合文 (compound statement)
******************************

複合文には、他の文 (のグループ) が入ります; 複合文は、中に入っている他
の文の実行の制御に何らかのやり方で影響を及ぼします。一般的には、複合文
は複数行にまたがって書かれますが、全部の文を一行に連ねた単純な書き方も
あります。

"if" 、 "while" 、および "for" 文は、伝統的な制御フロー構成を実現しま
す。 "try" は例外処理および/または一連の文に対するクリーンアップコード
を指定します。それに対して、 "with" 文はコードのかたまりの前後でコード
の初期化と終了処理を実行できるようにします。関数とクラス定義もまた、構
文的には複合文です。

複合文は、一つ以上の '節 (clause)' からなります。節は、ヘッダと 'スイ
ート (suite)' からなります。一つの複合文を成す各節のヘッダは、全て同じ
インデントレベルに置かれます。各節のヘッダは一意に識別するキーワードで
始まり、コロンで終わります。スイートは、節によって制御される文の集まり
です。スイートは、ヘッダがある行のコロンの後にセミコロンで区切って置か
れた一つ以上の単純文、または、ヘッダに続く行で一つ多くインデントされた
文の集まりです。後者の形式のスイートに限り、さらに複合文をネストできま
す; 以下の文は、 "else" 節がどちらの "if" 節に属するかがはっきりしない
などの理由から不正になります:

   if test1: if test2: print(x)

また、このコンテキスト中では、セミコロンによる結合はコロンより強いです
。従って、以下の例では、 "print()" の呼び出しはは全て実行されるか、全
く実行されないかのどちらかです:

   if x < y < z: print(x); print(y); print(z)

まとめると、以下のようになります:

   compound_stmt ::= if_stmt
                     | while_stmt
                     | for_stmt
                     | try_stmt
                     | with_stmt
                     | funcdef
                     | classdef
                     | async_with_stmt
                     | async_for_stmt
                     | async_funcdef
   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
   statement     ::= stmt_list NEWLINE | compound_stmt
   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]

なお、文は常に "NEWLINE" か、その後に "DEDENT" が続いたもので終了しま
す。また、オプションの継続節は必ず、文を開始できない予約語で始まるので
、曖昧さは存在しません。 (Python では、 'ぶら下がり (dangling) "else"'
問題は、ネストされた "if" 文をインデントさせることで解決されます)。

以下の節における文法規則の記述方式は、明確さのために、各節を別々の行に
書くようにしています。


8.1. "if" 文
============

"if" 文は、条件分岐を実行するために使われます:

   if_stmt ::= "if" assignment_expression ":" suite
               ("elif" assignment_expression ":" suite)*
               ["else" ":" suite]

"if" 文は、式を一つ一つ評価してゆき、真になるまで続けて、真になった節
のスイートだけを選択します (真: true と偽: false の定義については、 ブ
ール演算 (boolean operation) 節を参照してください); 次に、選択したスイ
ートを実行します (そして、 "if" 文の他の部分は、実行や評価をされません
)。全ての式が偽になった場合、 "else" 節があれば、そのスイートが実行さ
れます。


8.2. "while" 文
===============

"while" 文は、式の値が真である間、実行を繰り返すために使われます:

   while_stmt ::= "while" assignment_expression ":" suite
                  ["else" ":" suite]

"while" 文は式を繰り返し真偽評価し、真であれば最初のスイートを実行しま
す。式が偽であれば (最初から偽になっていることもありえます)、 "else"
節がある場合にはそれを実行し、ループを終了します。

最初のスイート内で "break" 文が実行されると、 "else" 節のスイートを実
行することなくループを終了します。 "continue" 文が最初のスイート内で実
行されると、スイート内にある残りの文の実行をスキップして、式の真偽評価
に戻ります。


8.3. "for" 文
=============

"for" 文は、シーケンス (文字列、タプルまたはリスト) や、その他の反復可
能なオブジェクト (iterable object) 内の要素に渡って反復処理を行うため
に使われます:

   for_stmt ::= "for" target_list "in" expression_list ":" suite
                ["else" ":" suite]

式リストは一度だけ評価されます。その結果はイテラブルオブジェクトになら
なければなりません。 "expression_list" の結果に対するイテレータが生成
されます。 その後、イテレータが与えるそれぞれの要素に対して、イテレー
タから返された順に一度づつ、スイートが実行されます。 それぞれの要素は
標準の代入規則 (代入文 (assignment statement) を参照してください) で
target_list に代入され、その後、スイートが実行されます。 全ての要素を
使い切ったとき (シーケンスが空であったり、イテレータが "StopIteration"
例外を送出したときは、即座に)、 "else" 節があればそれが実行され、ルー
プは終了します。

最初のスイートの中で "break" 文が実行されると、 "else" 節のスイートを
実行することなくループを終了します。 "continue" 文が最初のスイート内で
実行されると、スイート内にある残りの文の実行をスキップして、次の要素の
処理に移るか、これ以上次の要素が無い場合は "else" 節の処理に移ります。

for ループはターゲットリスト内の変数への代入を行います。 これにより、
for ループ内も含めて、それ以前の全ての代入は上書きされます:

   for i in range(10):
       print(i)
       i = 5             # this will not affect the for-loop
                         # because i will be overwritten with the next
                         # index in the range

ループが終了してもターゲットリスト内の名前は削除されませんが、イテラブ
ルが空の場合には、ループでの代入は全く行われません。ヒント: 組み込み関
数 "range()" は、 Pascal の "for i := a to b do" の効果をエミュレート
するのに適した、整数のイテレータを返します; すなわち、
"list(range(3))" はリスト "[0, 1, 2]" を返します。

注釈:

  ループ中でのシーケンスの変更には微妙な問題があります (これはミュータ
  ブルなシーケンスのみ、例えばリストで起こり得ます)。 どの要素が次に使
  われるかを追跡するために、内部的なカウンタが使われており、このカウン
  タは反復のたびに加算されます。 このカウンタがシーケンスの長さに達す
  ると、ループは終了します。 このことから、スイートの中でシーケンスか
  ら現在の (または以前の) 要素を除去すると、(次の要素の位置が、既に処
  理済みの現在の要素のインデックスになるために) 次の要素が飛ばされるこ
  とになります。 同様に、スイートの中でシーケンス中の現在の要素以前に
  要素を挿入すると、現在の要素がループの次の週で再度扱われることになり
  ます。 こうした仕様は、厄介なバグにつながります。 これは、シーケンス
  全体のスライスを使って一時的なコピーを作ることで避けられます。 例え
  ば次のようにします:

     for x in a[:]:
         if x < 0: a.remove(x)


8.4. "try" 文
=============

"try" 文は、ひとまとめの文に対して、例外処理および/またはクリーンアッ
プコードを指定します:

   try_stmt  ::= try1_stmt | try2_stmt
   try1_stmt ::= "try" ":" suite
                 ("except" [expression ["as" identifier]] ":" suite)+
                 ["else" ":" suite]
                 ["finally" ":" suite]
   try2_stmt ::= "try" ":" suite
                 "finally" ":" suite

The "except" clause(s) specify one or more exception handlers. When no
exception occurs in the "try" clause, no exception handler is
executed. When an exception occurs in the "try" suite, a search for an
exception handler is started.  This search inspects the except clauses
in turn until one is found that matches the exception.  An expression-
less except clause, if present, must be last; it matches any
exception.  For an except clause with an expression, that expression
is evaluated, and the clause matches the exception if the resulting
object is "compatible" with the exception.  An object is compatible
with an exception if the object is the class or a *non-virtual base
class* of the exception object, or a tuple containing an item that is
the class or a non-virtual base class of the exception object.

例外がどの "except" 節にも合致しなかった場合、現在のコードを囲うさらに
外側、そして呼び出しスタックへと検索を続けます。 [1]

"except" 節のヘッダにある式を値評価するときに例外が発生すると、元々の
ハンドラ検索はキャンセルされ、新たな例外に対する例外ハンドラの検索を現
在の "except" 節の外側のコードや呼び出しスタックに対して行います
("try" 文全体が例外を発行したかのように扱われます)。

対応する except 節が見つかると、except 節のスイートが実行されます。そ
の際、 "as" キーワードが存在すれば、その後で指定されているターゲットに
例外が代入されます。全ての "except" 節は実行可能なブロックを持っていな
ければなりません。このブロックの末尾に到達すると、通常は "try" 文全体
の直後から実行を継続します。(このことは、ネストされた二つの例外ハンド
ラが同じ例外に対して存在し、内側のハンドラ内の "try" 節で例外が発生し
た場合、外側のハンドラはその例外を処理しないことを意味します。)

例外が "as target" を使って代入されたとき、それは except 節の終わりに
消去されます。これはちょうど、以下のコード:

   except E as N:
       foo

が、以下のコードに翻訳されたかのようなものです:

   except E as N:
       try:
           foo
       finally:
           del N

よって、例外を except 節以降で参照できるようにするためには、別の名前に
代入されなければなりません。例外が削除されるのは、トレースバックが付与
されると、そのスタックフレームと循環参照を形作り、次のガベージ収集まで
そのフレーム内のすべての局所変数を生存させてしまうからです。

"except" 節のスイートが実行される前に、例外に関する詳細が "sys" モジュ
ールに保存され、 "sys.exc_info()" からアクセスできます。
"sys.exc_info()" は、例外クラス、例外インスタンス、そして例外が発生し
たプログラム上の位置を識別するトレースバックオブジェクト (標準型の階層
を参照してください) の 3 要素からなるタプルを返します。
"sys.exc_info()" の値は、例外を処理した関数から戻るときに、以前 (関数
呼び出し前) の値に戻されます。

オプションの "else" 節は、コントロールフローが "try" スイートを抜け、
例外が送出されず、 "return" 文、 "continue" 文、 "break" 文のいずれも
が実行されなかった場合に実行されます。 "else" 節で起きた例外は、手前に
ある "except" 節では処理されません。

"finally" 節がある場合は、 '後始末' の対処を指定します。まず "except"
節や "else" 節を含め、 "try" 節が実行されます。それらの節の中で例外が
起き、その例外が処理されていない場合には、例外は一時的に保存されます。
次に "finally" 節が実行されます。保存された例外があった場合は、
"finally" 節の末尾で再送出されます。 "finally" 節で別の例外が送出され
る場合は、保存されていた例外は新しい例外のコンテキストとして設定されま
す。 "finally" 節で "return" 文あるいは "break" 文を実行した場合は、保
存された例外は破棄されます:

   >>> def f():
   ...     try:
   ...         1/0
   ...     finally:
   ...         return 42
   ...
   >>> f()
   42

"finally" 節を実行している間は、プログラムからは例外情報は利用できませ
ん。

"try"..."finally" 文の "try" スイート内で "return" 、 "break" 、または
"continue" 文が実行された場合、 "finally" 節も、この文を '抜け出る途中
に' 実行されます。

関数の返り値は最後に実行された "return" 文によって決まります。
"finally" 節は必ず実行されるため、"finally" 節で実行された "return" 文
は常に最後に実行されることになります:

   >>> def foo():
   ...     try:
   ...         return 'try'
   ...     finally:
   ...         return 'finally'
   ...
   >>> foo()
   'finally'

例外に関するその他の情報は 例外 節にあります。また、 "raise" 文の使用
による例外の生成に関する情報は、 raise 文 節にあります。

バージョン 3.8 で変更: Python3.8 以前では、実装上の問題により
"finally" 節での "continue" 文は不正でした。


8.5. "with" 文
==============

"with" 文は、ブロックの実行を、コンテキストマネージャによって定義され
たメソッドでラップするために使われます (with文とコンテキストマネージャ
セクションを参照してください)。これにより、よくある
"try"..."except"..."finally" 利用パターンをカプセル化して便利に再利用
することができます。

   with_stmt ::= "with" with_item ("," with_item)* ":" suite
   with_item ::= expression ["as" target]

一つの "要素" を持つ "with" 文の実行は以下のように進行します:

1. コンテキスト式 ("with_item" で与えられた式) を評価することで、コン
   テキストマネージャを取得します。

2. コンテキストマネージャの "__enter__()" メソッドが、後で使うためにロ
   ードされます。

3. コンテキストマネージャの "__exit__()" メソッドが、後で使うためにロ
   ードされます。

4. コンテキストマネージャの "__enter__()" メソッドが呼ばれます。

5. "with" 文にターゲットが含まれていたら、それに "__enter__()" からの
   戻り値が代入されます。

   注釈:

     "with" 文は、 "__enter__()" メソッドがエラーなく終了した場合には
     "__exit__()" が常に呼ばれることを保証します。ですので、もしターゲ
     ットリストへの代入中にエラーが発生した場合には、これはそのスイー
     トの中で発生したエラーと同じように扱われます。以下のステップ 6 を
     参照してください。

6. スイートが実行されます。

7. コンテキストマネージャの "__exit__()" メソッドが呼ばれます。スイー
   トが例外によって終了されたのなら、その例外の型、値、トレースバック
   が "__exit__()" に引数として渡されます。そうでなければ、 3 つの
   "None" 引数が与えられます。

   スイートが例外により終了され、 "__exit__()" メソッドからの戻り値が
   偽（false）ならば、例外が再送出されます。この戻り値が真（true）なら
   ば例外は抑制され、実行は "with" 文の次の文から続きます。

   もしそのスイートが例外でない何らかの理由で終了した場合、その
   "__exit__()" からの戻り値は無視されて、実行は発生した終了の種類に応
   じた通常の位置から継続します。

以下のコード:

   with EXPRESSION as TARGET:
       SUITE

これは次と等価です:

   manager = (EXPRESSION)
   enter = type(manager).__enter__
   exit = type(manager).__exit__
   value = enter(manager)
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not exit(manager, *sys.exc_info()):
           raise
   finally:
       if not hit_except:
           exit(manager, None, None, None)

複数の要素があるとき、コンテキストマネージャは複数の "with" 文がネスト
されたかのように進行します:

   with A() as a, B() as b:
       SUITE

これは次と等価です:

   with A() as a:
       with B() as b:
           SUITE

バージョン 3.1 で変更: 複数のコンテキスト式をサポートしました。

参考:

  **PEP 343** - "with" ステートメント
     Python の "with" 文の仕様、背景、および例が記載されています。


8.6. 関数定義
=============

関数定義は、ユーザ定義関数オブジェクトを定義します (標準型の階層 節参
照):

   funcdef                   ::= [decorators] "def" funcname "(" [parameter_list] ")"
               ["->" expression] ":" suite
   decorators                ::= decorator+
   decorator                 ::= "@" assignment_expression NEWLINE
   parameter_list            ::= defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
                        | parameter_list_no_posonly
   parameter_list_no_posonly ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
                                 | parameter_list_starargs
   parameter_list_starargs   ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
                               | "**" parameter [","]
   parameter                 ::= identifier [":" expression]
   defparameter              ::= parameter ["=" expression]
   funcname                  ::= identifier

関数定義は実行可能な文です。関数定義を実行すると、現在のローカルな名前
空間内で関数名を関数オブジェクト (関数の実行可能コードをくるむラッパー
) に束縛します。この関数オブジェクトには、関数が呼び出された際に使われ
るグローバルな名前空間として、現在のグローバルな名前空間への参照が入っ
ています。

関数定義は関数本体を実行しません; 関数本体は関数が呼び出された時にのみ
実行されます。 [2]

関数定義は一つ以上の *デコレータ* 式でラップできます。デコレータ式は関
数を定義するとき、関数定義の入っているスコープで評価されます。その結果
は、関数オブジェクトを唯一の引数にとる呼び出し可能オブジェクトでなけれ
ばなりません。関数オブジェクトの代わりに、返された値が関数名に束縛され
ます。複数のデコレータはネストして適用されます。例えば、以下のようなコ
ード:

   @f1(arg)
   @f2
   def func(): pass

は、だいたい次と等価です

   def func(): pass
   func = f1(arg)(f2(func))

ただし、前者のコードでは元々の関数を "func" という名前へ一時的に束縛す
ることはない、というところを除きます。

バージョン 3.9 で変更: Functions may be decorated with any valid
"assignment_expression". Previously, the grammar was much more
restrictive; see **PEP 614** for details.

1 つ以上の *仮引数* が *parameter* "=" *expression* の形を取っていると
き、関数は "デフォルト引数値" を持つと言います。デフォルト値を持つ仮引
数では、呼び出し時にそれに対応する *実引数* は省略でき、その場合は仮引
数のデフォルト値が使われます。ある引数がデフォルト値を持っている場合、
それ以降 ""*"" が出てくるまでの引数は全てデフォルト値を持っていなけれ
ばなりません -- これは文法定義では表現されていない構文的制限です。

**デフォルト引数値は関数定義が実行されるときに左から右へ評価されます。
** これは、デフォルト引数の式は関数が定義されるときにただ一度だけ評価
され、同じ "計算済みの" 値が呼び出しのたびに使用されることを意味します
。この仕様を理解しておくことは特に、デフォルト引数値がリストや辞書のよ
うなミュータブルなオブジェクトであるときに重要です: 関数がこのオブジェ
クトを変更 (例えばリストに要素を追加) すると、このデフォルト値が変更の
影響を受けてしまします。一般には、これは意図しない動作です。このような
動作を避けるには、デフォルト値として "None" を使い、この値を関数本体の
中で明示的にテストします。例えば以下のようにします:

   def whats_on_the_telly(penguin=None):
       if penguin is None:
           penguin = []
       penguin.append("property of the zoo")
       return penguin

関数呼び出しの意味付けに関する詳細は、 呼び出し (call) 節で述べられて
います。 関数呼び出しを行うと、パラメタリストに記述された全てのパラメ
タに、位置引数、キーワード引数、デフォルト値のいずれかから値が代入され
ます。 ""*identifier"" 形式が存在すれば、余ったすべての位置引数を受け
取ったタプルに初期化されます。 このデフォルト値は空のタプルです。
""**identifier"" 形式が存在すれば、余ったすべてのキーワード引数を受け
取った順序付きのマッピングオブジェクトに初期化されます。 このデフォル
ト値は同じ型の空のマッピングオブジェクトです。 ""*"" や
""*identifier"" の後のパラメタはキーワード専用パラメータで、キーワード
引数によってのみ渡されます。 ""/"" の前のパラメタは位置専用パラメータ
で、位置引数によってのみ渡されます。

バージョン 3.8 で変更: The "/" function parameter syntax may be used
to indicate positional-only parameters. See **PEP 570** for details.

引数には、引数名に続けて "": expression"" 形式の *アノテーション* を付
けられます。 "*identifier" や "**identifier" の形式でも、すべての引数
にはアノテーションをつけられます。 関数には、引数リストの後に ""->
expression"" 形式の "return" アノテーションをつけられます。これらのア
ノテーションは、任意の有効な Python の式が使えます。 アノテーションが
あっても、関数の意味論は変わりません。 アノテーションの値は、関数オブ
ジェクトの "__annotations__" 属性の、引数名をキーとする値として得られ
ます。 "__future__" の "annotations" インポートを使った場合は、アノテ
ーションは実行時には文字列として保持され、これにより評価の遅延が可能に
なっています。 そうでない場合は、アノテーションは関数定義が実行された
ときに評価されます。 このケースでは、アノテーションはソースコードに現
れたのとは違う順序で評価されることがあります。

式を即時に使用するために、無名関数 (名前に束縛されていない関数) を作成
することもできます。 これは ラムダ (lambda) の節で解説されているラムダ
式を使います。 ラムダ式は簡略化された関数定義の簡略表現に過ぎないこと
に注意してください;  ""def"" 文で定義された関数もラムダ式で作成された
関数のように、引数として渡せたり、他の名前に割り当てることができます。
複数の式とアノテーションが実行できるので、 ""def"" 形式の方がより強力
です。

**プログラマへのメモ:** 関数は第一級オブジェクトです。関数定義内で実行
された ""def"" 文は、返り値や引数として渡せるローカル関数を定義します
。ネストした関数内で使われる自由変数は、 def を含んでいる関数のローカ
ル変数にアクセスできます。詳細は 名前づけと束縛 (naming and binding)
節を参照してください。

参考:

  **PEP 3107** - Function Annotations
     関数アノテーションの元の仕様書。

  **PEP 484** - 型ヒント
     アノテーションの標準的な意味付けである型ヒントの定義。

  **PEP 526** - Syntax for Variable Annotations
     クラス変数とインスタンス変数を含む変数に型ヒントが宣言できる機能

  **PEP 563** - アノテーションの遅延評価
     実行時にアノテーションを貪欲評価するのではなく文字列形式で保持す
     ることによる、アノテーションにおける前方参照のサポート


8.7. クラス定義
===============

クラス定義は、クラスオブジェクトを定義します (標準型の階層 節参照):

   classdef    ::= [decorators] "class" classname [inheritance] ":" suite
   inheritance ::= "(" [argument_list] ")"
   classname   ::= identifier

クラス定義は実行可能な文です。継承リストは通常、基底クラスリストを与え
ます (より高度な使い方は、 メタクラス を参照してください)。ですから、
リストのそれぞれの要素の評価はサブクラス化しても良いクラスであるべきで
す。継承リストのないクラスは、デフォルトで、基底クラス "object" を継承
するので:

   class Foo:
       pass

は、以下と同等です

   class Foo(object):
       pass

次にクラスのスイートが、新たな実行フレーム (名前づけと束縛 (naming and
binding) を参照してください) 内で、新たに作られたローカル名前空間と元
々のグローバル名前空間を使って実行されます (通常、このスイートには主に
関数定義が含まれます)。クラスのスイートが実行し終えると、実行フレーム
は破棄されますが、ローカルな名前空間は保存されます。[3] 次に、継承リス
トを基底クラスに、保存されたローカル名前空間を属性値辞書に、それぞれ使
ってクラスオブジェクトが生成されます。最後に、もとのローカル名前空間に
おいて、クラス名がこのクラスオブジェクトに束縛されます。

クラス本体で属性が定義された順序は新しいクラスの "__dict__" に保持され
ます。 この性質が期待できるのは、クラスが作られた直後かつ定義構文を使
って定義されたクラスであるときのみです。

クラス作成は、 メタクラス を利用して大幅にカスタマイズできます。

関数をデコレートするのと同じように、クラスもデコレートすることが出来ま
す、

   @f1(arg)
   @f2
   class Foo: pass

は、だいたい次と等価です

   class Foo: pass
   Foo = f1(arg)(f2(Foo))

デコレータ式の評価規則は関数デコレータと同じです。結果はクラス名に束縛
されます。

バージョン 3.9 で変更: Classes may be decorated with any valid
"assignment_expression". Previously, the grammar was much more
restrictive; see **PEP 614** for details.

**プログラマのための注釈:** クラス定義内で定義された変数はクラス属性で
あり、全てのインスタンス間で共有されます。インスタンス属性は、メソッド
の中で "self.name = value" とすることで設定できます。クラス属性もイン
スタンス属性も ""self.name"" 表記でアクセスでき、この表記でアクセスし
たとき、インスタンス属性は同名のクラス属性を隠蔽します。クラス属性は、
インスタンス属性のデフォルト値として使えますが、そこにミュータブルな値
を使うと予期せぬ結果につながります。 記述子 を使うと、詳細な実装が異な
るインスタンス変数を作成できます。

参考:

  **PEP 3115** - Metaclasses in Python 3000
     メタクラスの宣言を現在の文法と、メタクラス付きのクラスがどのよう
     に構築されるかの意味論を変更した提案

  **PEP 3129** - クラスデコレータ
     クラスデコレータを追加した提案。 関数デコレータとメソッドデコレー
     タは **PEP 318** で導入されました。


8.8. コルーチン
===============

バージョン 3.5 で追加.


8.8.1. コルーチン関数定義
-------------------------

   async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")"
                     ["->" expression] ":" suite

Python で実行しているコルーチンは多くの時点で一時停止と再開ができます
(*コルーチン* を参照してください)。

Functions defined with "async def" syntax are always coroutine
functions, even if they do not contain "await" or "async" keywords.

コルーチン関数の本体の中で "yield from" 式を使用すると "SyntaxError"
になります。

コルーチン関数の例:

   async def func(param1, param2):
       do_stuff()
       await some_coroutine()


8.8.2. "async for" 文
---------------------

   async_for_stmt ::= "async" for_stmt

*asynchronous iterable* は、その "__anext__" メソッドで非同期なコード
を実行可能な、*asynchronous iterator* を直接返す "__aiter__" メソッド
を提供しています。

"async for" 文によって非同期なイテラブルを簡単にイテレーションすること
ができます。

以下のコード:

   async for TARGET in ITER:
       SUITE
   else:
       SUITE2

は意味論的に以下と等価です:

   iter = (ITER)
   iter = type(iter).__aiter__(iter)
   running = True

   while running:
       try:
           TARGET = await type(iter).__anext__(iter)
       except StopAsyncIteration:
           running = False
       else:
           SUITE
   else:
       SUITE2

詳細は "__aiter__()" や "__anext__()" を参照してください。

コルーチン関数の本体の外で "async for" 文を使用すると "SyntaxError" に
なります。


8.8.3. "async with" 文
----------------------

   async_with_stmt ::= "async" with_stmt

*asynchronous context manager* は、 *enter* メソッドと *exit* メソッド
内部で実行を一時停止できる *context manager* です。

以下のコード:

   async with EXPRESSION as TARGET:
       SUITE

これは次と等価です:

   manager = (EXPRESSION)
   aenter = type(manager).__aenter__
   aexit = type(manager).__aexit__
   value = await aenter(manager)
   hit_except = False

   try:
       TARGET = value
       SUITE
   except:
       hit_except = True
       if not await aexit(manager, *sys.exc_info()):
           raise
   finally:
       if not hit_except:
           await aexit(manager, None, None, None)

詳細は "__aenter__()" や "__aexit__()" を参照してください。

コルーチン関数の本体の外で "async with" 文を使用すると "SyntaxError"
になります。

参考:

  **PEP 492** - async 構文および await 構文付きのコルーチン
     コルーチンを Python のまともな独り立ちした概念にし、サポートする
     構文を追加した提案。

-[ 脚注 ]-

[1] 例外は、別の例外を送出するような "finally" 節が無い場合にのみ呼び
    出しスタックへ伝わります。新しい例外によって、古い例外は失われます
    。

[2] 関数の本体の最初の文として現われる文字列リテラルは、その関数の
    "__doc__" 属性に変換され、その関数の *ドキュメンテーション文字列*
    になります。

[3] クラスの本体の最初の文として現われる文字列リテラルは、その名前空間
    の "__doc__" 要素となり、そのクラスの *ドキュメンテーション文字列*
    になります。
