ホームページ >バックエンド開発 >Python チュートリアル >Python の割り当てが可変オブジェクトで予期しない動作を示すのはなぜですか?

Python の割り当てが可変オブジェクトで予期しない動作を示すのはなぜですか?

DDD
DDDオリジナル
2024-12-07 20:25:16482ブラウズ

Why Does Python Assignment Show Unexpected Behavior with Mutable Objects?

Python 割り当てにおけるコピースルー動作

はじめに

人気のあるプログラミング言語である Python は、次の場合に特有の動作を示します。代入演算子 (=) を使用してオブジェクトを変数に代入します。この動作は一般にコピースルーと呼ばれ、多くの場合、予期しない結果を引き起こします。この概念を解明するために、一般的な例を見てみましょう。

問題: コピースルーとコピー

次のコードを考えてみましょう:

dict_a = dict_b = dict_c = {}
dict_c['hello'] = 'goodbye'

print(dict_a)
print(dict_b)
print(dict_c)

このコードでは、3 つの個別の辞書を作成し、それらを空に初期化し、dict_c のみを変更すると予想されます。予期される出力は次のようになります:

{}
{}
{'hello': 'goodbye'}

ただし、Python のコピースルー動作により異なる結果が生成されます:

{'hello': 'goodbye'}
{'hello': 'goodbye'}
{'hello': 'goodbye'}

説明: 参照割り当て

この動作を理解する鍵は、Python の変数の性質にあります。 Python では、変数 (または名前) は、メモリに格納されている実際のオブジェクトへの単なるポインタです。ある変数を別の変数に代入すると、代入演算子 (=) によってメモリ アドレス (またはポインタ) が 1 つの変数から別の変数にコピーされます。この例では:

dict_a = dict_b = dict_c

これは、dict_a、dict_b、および dict_c がすべてメモリ内の同じ辞書オブジェクトを指していることを意味します。したがって、dict_c が変更されると、3 つの変数すべてが同じ変更を受け、コピースルー効果が発生します。

問題の解決: コピー メソッドの使用

防止するにはコピースルー動作では、基礎となるオブジェクトのコピーを明示的に作成する必要があります。 Python は、この目的のために 2 つのメソッドを提供します。

  • dict.copy(): 辞書の最上位要素をコピーする浅いコピーを作成します。
  • copy.deepcopy(): 内部のすべてのネストされたオブジェクトを再帰的にコピーするディープ コピーを作成します。 Dictionary.

例:

dict_a = dict_b.copy()
dict_c = copy.deepcopy(dict_a)

dict_c['hello'] = 'goodbye'

print(dict_a)  # {'hello': 'goodbye'} (shallow copy, affected)
print(dict_b)  # {} (unaffected)
print(dict_c)  # {'hello': 'goodbye'} (deep copy, unaffected)

これらのコピー メソッドを使用すると、オブジェクトの独立したコピーを作成し、コピースルー動作を回避できます。

以上がPython の割り当てが可変オブジェクトで予期しない動作を示すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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