ホームページ >バックエンド開発 >Python チュートリアル >Python の可変デフォルト引数の動作が予期しない蓄積を引き起こすのはなぜですか?

Python の可変デフォルト引数の動作が予期しない蓄積を引き起こすのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-22 15:42:16557ブラウズ

Why Does Python's Mutable Default Argument Behavior Lead to Unexpected Accumulation?

「最小の驚き」と可変デフォルト引数

Python の可変デフォルト引数の動作は、初心者も経験豊富な開発者も同様に長い間困惑させてきました。 foo(a=[]) のような関数は、複数の呼び出しにわたって予期せず a に値を蓄積するため、多くの人がその理論的根拠に疑問を抱いています。

この一見欠陥のある設計の根本を理解するには、Python 関数の性質を深く掘り下げる必要があります。最高級のオブジェクトとして。関数が定義されると、それは基本的にオブジェクト自体として評価されます。これは、この例の a=[] のようなデフォルトのパラメータが関数オブジェクトの属性になることを意味します。

したがって、関数が呼び出されるとき、評価されるのはデフォルトのパラメータ値ではなく、関数定義時に作成されたリストオブジェクトを指す属性。結果として、関数内でリストに加えられた変更は共有参照に影響し、a の累積動作を説明します。

このアプローチは、一貫性とオブジェクトへの準拠を優先する Python の「最小の驚き」哲学と一致しています。指向された原則。クラスのインスタンス変数が時間の経過とともに変化する可能性があるのと同様に、関数オブジェクトの「メンバー データ」も変化します。

この動作には実用的な目的もあります。これにより、関数が呼び出し間で持続する状態を保持できるようになります。次の例を考えてみましょう。

def a():
    print("a executed")
    return []

def b(x=a()):
    x.append(5)
    print(x)

a executed
>>> b()
[5]
>>> b()
[5, 5]

ここでは、a() によって返された値が b() へのすべての呼び出しで共有されるため、複数の反復にわたってリストを変更および保持できます。関数の実行時にデフォルトの引数をバインドすると、b() が呼び出されるたびに事実上新しいリストが作成され、この動作が不可能になります。

結論として、Python の変更可能なデフォルト引数の動作は、最初は直観に反しているように見えるかもしれませんが、その原因は次のとおりです。この言語のファーストクラスの関数の性質は、オブジェクト指向プログラミングと一貫性の原則と一致しています。

以上がPython の可変デフォルト引数の動作が予期しない蓄積を引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。