#
7.5 関数定義

関数定義は、ユーザ定義関数オブジェクトを定義します ( 3.2 節参照):

  `funcdef` | ::= | `"def" funcname "(" [parameter_list] ")" ":" suite`
  `parameter_list` | ::= | `(defparameter ",")*`
  |  | `( "*" identifier [, "**" identifier]`
  |  | `| "**" identifier`
  |  | `| defparameter [","])`
  `defparameter` | ::= | `parameter ["=" expression]`
  `sublist` | ::= | `parameter ("," parameter)* [","]`
  `parameter` | ::= | `identifier | "(" sublist ")"`
  `funcname` | ::= | `identifier`

  Download entire grammar as text.

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

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

一つ以上のトップレベルのパラメタに 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

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

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

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