1

重複の可能性:
Pythonの「驚き最小の原則」:
奇妙な動作を拡張する可変デフォルト引数リスト
メソッド名を使用したピラミッドトラバーサルビュールックアップ

私がこの関数を持っているとしましょう:

def a(b=[]):
    b += [1]
    print b

それを呼び出すと、次の結果が得られます。

>>> a()
[1]
>>> a()
[1, 1]
>>> a()
[1, 1, 1]

に変更b += [1]するb = b + [1]と、関数の動作が変わります。

>>> a()
[1]
>>> a()
[1]
>>> a()
[1]

とどうb = b + [1]違うのb += [1]?なぜこれが起こるのですか?

4

3 に答える 3

5

b += [1]関数のデフォルトを変更します(驚き最小のFAQにつながります)。b = b + [1]デフォルトの引数を取りますb-を使用して新しいリストを作成し+ [1]、それをにバインドしbます。1つはリストを変更し、もう1つは新しいリストを作成します。

于 2012-12-29T19:11:05.797 に答える
5

Pythona += bでは、と同じことを行う保証はありませんa = a + b

リストの場合、基本的にはと同等の場所でsomeList += otherList変更し、名前を同じリストに再バインドします。 一方、は、2つのリストを連結して新しいリストを作成し、その名前をその新しいリストにバインドします。someListsomeList.extend(otherList)someListsomeList = someList + otherListsomeList

つまり、+=の場合、名前はすでに指しているのと同じオブジェクトを指していることになり、の場合、名前+は新しいオブジェクトを指します。関数のデフォルトは一度だけ評価されるため(このよく引用される質問を参照)、これは、+=すべてが同じ元のオブジェクト(デフォルトの引数)を変更するため、操作が積み重なることを意味します。

于 2012-12-29T19:15:54.380 に答える
0

関数を定義するとき

>>> def a(b=[]):
    b += [1]
    return b

すべてのデフォルト引数を特別な場所に保存します。実際には次の方法でアクセスできます。

>>> a.func_defaults
([],)

最初のデフォルト値は次のlistとおりです。IDは次のとおりです。

>>> id(a.func_defaults[0])
15182184

関数を呼び出してみましょう:

>>> print a()
[1]
>>> print a()
[1, 1]

返された値のIDを確認してください。

>>> print id(a())
15182184
>>> print id(a())
15182184

ご覧のとおり、これは最初のデフォルト値のリストのIDと同じです。

b+=...関数の異なる出力は、インプレースを変更しb、新しいリストを作成しないという事実によって説明されます。そしてb、デフォルト値のタプルに保持されているリストです。したがって、リストへのすべての変更はそこに保存され、関数の各呼び出しは、の異なる値で機能しますb

于 2012-12-29T19:27:52.963 に答える