# 7. 複合文 (compound statement)

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

`if` 、 `while` 、および `for` 文は、伝統的な制御フロー構成を実現します。 `try` は例外処理および / または一連の文に対するクリーンアップコードを指定します。関数とクラス定義もまた、構文法的には複合文です。

複合文は、一つまたはそれ以上の ' 節 (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
                       | decorated
    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` 文はインデントさせること解決しています ) 。

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

## 7.1. `if` 文

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

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

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

## 7.2. `while` 文

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

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

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

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

## 7.3. `for` 文

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

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

式リストは一度だけ評価されます ; 結果はイテレーション可能オブジェクトにならねばなりません。 `expression_list` の結果に対してイテレータを生成し、その後、シーケンスの各要素についてインデクスの小さい順に一度だけスイートを実行します。このときシーケンス内の要素が通常の代入規則を使ってターゲットリストに代入され、その後スイートが実行されます。全ての要素を使い切ると ( シーケンスが空の場合にはすぐに ) 、 `else` 節があればそれが実行され、ループを終了します。

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

スイートの中では、ターゲットリスト内の変数に代入を行えます; この代入によって、次に代入される要素に影響を及ぼすことはありません。

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

注釈

There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, e.g. lists). An internal counter is used to keep track of which item is used next, and this is incremented on each iteration. When this counter has reached the length of the sequence the loop terminates. This means that if the suite deletes the current (or a previous) item from the sequence, the next item will be skipped (since it gets the index of the current item which has already been treated). Likewise, if the suite inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop. This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole sequence, e.g.,

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

## 7.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

バージョン 2.5 で変更: 以前のバージョンの Python では、 `try`... `except`... `finally` は機能しませんでした。 `try`... `except` は `try`... `finally` 中でネストさせる必要がありました。

`except` 節は一つ以上の例外ハンドラを指定します。 `try` 節内で例外が起きなければ、どの例外ハンドラも実行されません。 `try` スイート内で例外が発生すると、例外ハンドラの検索が開始されます。この検索では、 `except` 節を逐次、発生した例外に対応するまで調べます。式を伴わない `except` 節を使うなら、最後に書かなければならず、これは全ての例外に対応します。式を伴う `except` 節に対しては、その式が評価され、結果のオブジェクトが例外と "互換である (compatible)" 場合にその節が対応します。ある例外に対してオブジェクトが互換であるのは、それが例外オブジェクトのクラスかベースクラスの場合、または例外と互換である要素が入ったタプルである場合です。

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

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

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

`except` 節のスイートが実行される前に、例外に関する詳細が `sys` モジュール内の三つの変数に代入されます : `sys.exc_type` は、例外を示すオブジェクトを受け取ります ; `sys.exc_value` は例外のパラメタを受け取ります ; `sys.exc_traceback` は、プログラム上の例外が発生した位置を識別するトレースバックオブジェクト (標準型の階層 参照 ) を受け取ります。これらの詳細はまた、関数 `sys.exc_info()` を介して入手することもできます。この関数はタプル `(exc_type, exc_value, exc_traceback)` を返します。ただしこの関数に対応する変数の使用は、スレッドを使ったプログラムで安全に使えないため撤廃されています。 Python 1.5 からは、例外を処理した関数から戻るときに、以前の値 ( 関数呼び出し前の値 ) に戻されます。

The optional `else` clause is executed if the control flow leaves the `try` suite, no exception was raised, and no `return`, `continue`, or `break` statement was executed. Exceptions in the `else` clause are not handled by the preceding `except` clauses.

`finally` 節がある場合は、 '後始末 (cleanup)' の対処を指定します。まず `except` 節や `else` 節を含め、 `try` 節が実行されます。それらの節の中で例外が起き、誰も対処していない場合は、例外は一時的に保存されます。次に `finally` 節が実行されます。保存された例外があった場合は、 `finally` 節の末尾で再送出されます。 `finally` 節で別の例外が送出される場合、あるいは `return`, `break` 文を実行した場合は、保存された例外は破棄されます:

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

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

`try`...`finally` 文の `try` スイート内で `return` 、 `break` 、または `continue` 文が実行された場合、 `finally` 節も '抜け出る途中に (on the way out)' 実行されます。 `finally` 節での `continue` 文の使用は不正です。 (理由は現在の実装上の問題です -- この制限は将来解消されるかもしれません)。

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

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

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

## 7.5. `with` 文

バージョン 2.5 で追加.

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

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

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

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

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

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

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

   注釈

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

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

6. コンテキストマネージャの `__exit__()` メソッドが呼ばれます。もし例外がスイートを終了させる場合、その型、値、そしてトレースバックが `__exit__()` へ引数として渡されます。そうでなければ、 3 つの `None` 引数が与えられます。

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

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

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

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

は、以下と同等です

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

注釈

Python 2.5 では、 `with` 文は `with_statement` 機能が有効にされた場合にだけ利用できます。 Python 2.6 では常に利用できます。

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

参考

PEP 343 - "with" ステートメント

  Python の `with` 文の仕様、背景、そして実例

## 7.6. 関数定義

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

    decorated      ::=  decorators (classdef | funcdef)
    decorators     ::=  decorator+
    decorator      ::=  "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
    funcdef        ::=  "def" funcname "(" [parameter_list] ")" ":" suite
    dotted_name    ::=  identifier ("." identifier)*
    parameter_list ::=  (defparameter ",")*
                        (  "*" identifier ["," "**" identifier]
                        | "**" identifier
                        | defparameter [","] )
    defparameter   ::=  parameter ["=" expression]
    sublist        ::=  parameter ("," parameter)* [","]
    parameter      ::=  identifier | "(" sublist ")"
    funcname       ::=  identifier

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

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

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

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

は、以下と同じです

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

一つ以上のトップレベルの parameters に parameter `=` expression の形式がある場合、関数は " デフォルトのパラメタ値 (default parameter values)" を持つといいます。デフォルト値を伴うパラメタに対しては、関数呼び出しの際に対応する引数(argument)が省略されると、パラメタの値はデフォルト値で置き換えられます。あるパラメタがデフォルト値を持つ場合、それ以後のパラメタは全てデフォルト値を持たなければなりません --- これは文法的には表現されていない構文上の制限です。

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

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

関数呼び出しの意味付けに関する詳細は、 呼び出し (call) 節で述べられています。関数呼び出しを行うと、パラメタリストに記述された全てのパラメタに対して、固定引数、キーワード引数、デフォルト引数のいずれかから値を代入します。 "`*identifier`" 形式が存在する場合、余った固定引数を受け取るタプルに初期化されます。この変数のデフォルト値は空のタプルです。 "`**identifier`" 形式が存在する場合、余ったキーワード引数を受け取るタプルに初期化されます。デフォルト値は空の辞書です。

式で直接使うために、無名関数 ( 名前に束縛されていない関数 ) を作成することも可能です。無名関数の作成には、 ラムダ (lambda) 節で記述されているラムダ式 (lambda expression) を使います。ラムダ式は、単純化された関数定義を行うための略記法にすぎません ; "`def`" 文で定義された関数は、ラムダ式で定義された関数と全く同様に引渡したり、他の名前に代入したりできます。実際には、 "`def`" 形式は複数の式を実行できるという点でより強力です。

** プログラマのための注釈 :** 関数は一級の (first-class) オブジェクトです。関数定義内で "`def`" 形式を実行すると、戻り値として返したり引き渡したりできるローカルな関数を定義します。ネストされた関数内で自由変数を使うと、 `def` 文の入っている関数のローカル変数にアクセスすることができます。詳細は 名前づけと束縛 (naming and binding) 節を参照してください。

## 7.7. クラス定義

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

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

クラス定義は実行可能な文です。クラス定義では、まず継承リストがあればそれを評価します。継承リストの各要素の値評価結果はクラスオブジェクトか、サブクラス可能なクラス型でなければなりません。次にクラスのスイートが新たな実行フレーム内で、新たなローカル名前空間と元々のグローバル名前空間を使って実行されます (名前づけと束縛 (naming and binding) 節を参照してください ) 。 ( 通常、スイートには関数定義のみが含まれます ) クラスのスイートを実行し終えると、実行フレームは無視されますが、ローカルな名前空間は保存されます。次に、基底クラスの継承リストを使ってクラスオブジェクトが生成され、ローカルな名前空間を属性値辞書として保存します。最後に、もとのローカルな名前空間において、クラス名がこのクラスオブジェクトに束縛されます。

** プログラマのための注釈 :** クラス定義内で定義された変数はクラス変数です ; クラス変数は全てのインスタンス間で共有されます。インスタンス変数を作成するには、メソッドの中で `self.name = value` でセットできます。クラス変数もインスタンス変数も "`self.name`" 表記でアクセスすることができます。この表記でアクセスする場合、インスタンス変数は同名のクラス変数を隠蔽します。クラス変数は、インスタンス変数のデフォルト値として使えますが、変更可能な値をそこに使うと予期せぬ結果につながります。新スタイルクラス (new-style class) では、デスクリプタを使ってインスタンス変数の振舞いを変更できます。

クラス定義は、関数定義と同じように、 1 つ以上のデコレータ (decorator) 式でラップすることができます。デコレータ式の評価規則は関数と同じです。結果はクラスオブジェクトでなければならず、それがクラス名に束縛されます。

注記

1

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

2

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

3

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