web-dev-qa-db-ja.com

Python関数とそのデフォルト値のオプションのパラメーター

可能性のある複製:
Pythonの「Least Astonishment」:可変デフォルト引数

Python関数/メソッド。

次のコードブロックがあります。

_>>> def F(a, b=[]):
...     b.append(a)
...     return b
...
>>> F(0)
[0]
>>> F(1)
[0, 1]
>>>
_

なぜF(1)は_[0, 1]_ではなく_[1]_を返すのですか?

つまり、内部で何が起こっているのか

35
Oscar Mederos

数年前のPyConの優れたドキュメント- デフォルトのパラメーター値の説明 。しかし基本的に、リストは可変オブジェクトであり、キーワード引数は関数定義時に評価されるため、関数を呼び出すたびに同じデフォルト値が取得されます。

これを行う正しい方法は次のとおりです。

def F(a, b=None):
    if b is None:
        b = []
    b.append(a)
    return b
43
Ben Hayden

デフォルトのパラメーター は、非常に直感的には、関数オブジェクトのメンバー変数に似ています。

関数定義が実行されると、デフォルトのパラメーター値が評価されます。これは、式が関数が定義されたときに1回評価され、同じ「事前に計算された」値が各呼び出しに使用されることを意味します。これは、デフォルトパラメータがリストや辞書などの可変オブジェクトである場合を理解するために特に重要です:関数がオブジェクトを変更する場合(たとえば、リストにアイテムを追加することにより)、デフォルト値が実際に変更されます。

http://docs.python.org/reference/compound_stmts.html#function

リストは変更可能なオブジェクトです。内容を変更できます。既定のリスト(または辞書、またはセット)を取得する正しい方法は、関数内で代わりに実行時に作成することです。

def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list
9
Jonas Elfström