目次

前のトピックへ

単純文 (simple statement)

次のトピックへ

トップレベル要素

このページ

複合文 (compound statement)

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

ifwhile 、および 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 文はインデントさせること解決しています)。

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

if

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

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

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

while

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

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

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

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

for

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

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

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

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

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

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

警告

ループ中のシーケンスの変更には微妙な問題があります (これは変更可能なシーケンス、すなわちリストで起こります)。 どの要素が次に使われるかを追跡するために、内部的なカウンタが使われており、このカウンタは反復処理を行うごとに加算されます。 このカウンタがシーケンスの長さに達すると、ループは終了します。このことは、スイート中でシーケンスから現在の (または以前の) 要素を 除去すると、(次の要素のインデクスは、すでに取り扱った要素のインデクスになるために) 次の要素が飛ばされることを意味します。 同様に、スイート中でシーケンス中の現在の要素以前に要素を挿入すると、ループ中で現在の要素が再度扱われることになります。 こうした仕様は、厄介なバグになります。シーケンス全体に相当するスライスを使って一時的なコピーを作ると、これを避けることができます。

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

try

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

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

バージョン 2.5 で変更: 以前のバージョンの Python では、 try...except...finally が機能しませんでした。 try...excepttry...finally 中でネストされなければいけません。.

except 節は一つまたはそれ以上の例外ハンドラを指定します。 try 節内で全く例外が起きなければ、どの例外ハンドラも実行されません。 try スイート内で例外が発生すると、 例外ハンドラの検索が開始されます。この検索では、 except 節を逐次調べて、発生した例外に合致するまで続けます。式を伴わない 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 からは、例外を処理した関数から戻るときに、以前の値 (関数呼び出し前の値) に戻されます。

オプションの else 節は、実行の制御が try 節の末尾に到達した場合に実行されます。 [2] else 節内で起きた例外は、 else 節に先行する except 節で処理されることはありません。

finally が存在する場合、これは ‘クリーンアップ’ ハンドラを指定しています。 exceptelse 節を含む try 節が実行されます。それらの節のいずれかで例外が発生して処理されない場合、 その例外は一時的に保存されます。 finally 節が実行されます。もし保存された例外が存在する場合、それは finally 節の最後で再送出されます。 finally 節で別の例外が送出されたり、 returnbreak 節が実行された場合、保存されていた 例外は失われます。例外情報は、 finally 節の実行中にはプログラムで取得することができません。

try...finally 文の try スイート内で returnbreak 、または continue 文が 実行された場合、 finally 節も ‘抜け出る途中に (on the way out)’ 実行されます。

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

with

バージョン 2.5 で追加.

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

with_stmt ::=  "with" expression ["as" target] ":" suite

with 文の実行は以下のように進行します:

  1. コンテキスト式を評価し、コンテキストマネージャを取得します。

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

  3. ターゲットが with 文に含まれる場合、 __enter__() からの戻り値がこれに代入されます。

    ノート

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

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

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

    スイートが例外により終了した場合、 __exit__() メソッドからの戻り値は偽(false)であり、例外が 再送出されます。この戻り値が真(true)ならば例外は抑制され、そして実行は with 文に続く分へ継続されます。

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

ノート

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

参考

PEP 0343 - The “with” statement
Python の with 文の仕様、背景、そして実例

関数定義

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

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

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

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

関数定義は一つまたは複数のデコレータ(decorator)式でラップできます。 デコレータ式は関数を定義する時点で、関数定義の入っているスコープにおいて評価されます。デコレータは呼び出し可能オブジェクトを返さねば なりません。また、デコレータのとれる引数は関数オブジェクトひとつだけです。デコレータの返す値は関数オブジェクトではなく、関数名にバインドされます。 複数のデコレータを入れ子にして適用してもかまいません。例えば、以下のようなコード:

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

は、

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

と同じです。

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

デフォルトパラメタ値は関数定義を実行する際に値評価されます。 これは、デフォルトパラメタの式は関数を定義するときにただ一度だけ評価され、同じ “計算済みの” 値が全ての呼び出しで使われることを意味します。デフォルトパラメタ値がリストや辞書のような変更可能なオブジェクトである 場合、この使用を理解しておくことは特に重要です: 関数でこのオブジェクトを (例えばリストに要素を追加して) 変更すると、実際のデフォルト 値が変更されてしまいます。一般には、これは意図しない動作です。このような動作を避けるには、デフォルト値に 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 form) を使います。ラムダ形式は、単純化された関数定義を行うための略記法にすぎません; “def” 文で定義された関数は、ラムダ形式で定義された関数と全く同様に引渡したり、他の名前に代入したりできます。実際には、”def” 形式は複数の式を実行できるという点でより強力です。

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

クラス定義

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

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

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

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

Class definitions, like function definitions, may be wrapped by one or more decorator expressions. The evaluation rules for the decorator expressions are the same as for functions. The result must be a class object, which is then bound to the class name. クラス定義は、関数定義と同じように、1つ以上のデコレータ(decorator)式でラップすることができます。 デコレータ式の評価は関数と同じです。結果はクラスオブジェクトでなければならず、 それがクラス名に束縛されます。

脚注

[1]例外は、例外を打ち消す finally 節が無い場合にのみ呼び出しスタックへ伝わります。
[2]現在、制御が “末尾に到達する” のは、例外が発生したり、 return, continue, または break 文が実行される場合を除きます。
[3]関数の本体の最初の文として現われる文字列リテラルは、その関数の __doc__ 属性に変換され、その関数のドキュメンテーション文字列(docstring) になります。
[4]クラスの本体の最初の文として現われる文字列リテラルは、その名前空間の __doc__ 要素となり、そのクラスのドキュメンテーション文字列(docstring)になります。