ホームページ >バックエンド開発 >Python チュートリアル >Pythonオブジェクトのディープコピーとシャローコピーについて詳しく解説

Pythonオブジェクトのディープコピーとシャローコピーについて詳しく解説

WBOY
WBOYオリジナル
2016-06-16 08:42:341413ブラウズ

この記事の内容を「Python Core Programming 2」で拝見し、参考になると思い書きました!

浅いコピー

まず、オブジェクトをコピーするために 2 つのメソッドを使用します。1 つはスライスで、もう 1 つはファクトリメソッドです。次に、id 関数を使用して識別子を確認します

コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8

obj = ['名前',['年齢',18]]
a=obj[:]
b=リスト(obj)
obj,a,b の x の場合:
ID(x) を印刷

35217032
35227912
29943304


それらの ID はすべて異なります。通常の判断では、3 つの異なる ID を持つオブジェクトは独立しているはずです。それなら、まず名前を変更しましょう
コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8

obj = ['名前',['年齢',18]]
a=obj[:]
b=リスト(obj)
obj,a,b の x の場合:
ID(x) を印刷

a[0] = 'リシ'
b[0] = '張三'


を印刷します 印刷 b

35217032
35227912
33547784
['リシ', ['年齢', 18]]
['張三', ['年齢', 18]]

オブジェクト a と b にはそれぞれ異なる名前が付けられています。オブジェクト a の年齢の変更を見てみましょう
コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8

obj = ['名前',['年齢',18]]
a=obj[:]
b=リスト(obj)
obj,a,b の x の場合:
ID(x) を印刷

a[0] = 'リシ'
b[0] = '張三'


を印刷します 印刷 b

a[1][1] = 25


を印刷します 印刷 b

35217032
35227912
29943304
['リシ', ['年齢', 18]]
['張三', ['年齢', 18]]
['リシ', ['年齢', 25]]
['張三', ['年齢', 25]]

注意深い人なら、a[0] 要素と b[0] 要素を変更しても相互に影響がないことに気づいたはずです。なぜ a[1][1] の要素を変更すると b[1][1] の要素に影響を与えるのでしょうか。 】?
この問題を解決するには、まずディープ コピーとシャロー コピーを理解する必要があります。上の例では、作成した a と b は obj オブジェクトの浅いコピーで、obj の最初の要素は文字列で不変型、2 番目の要素はリストで可変型です。したがって、オブジェクトをコピーすると、文字列が明示的にコピーされて新しい文字列が作成されますが、リストは参照のみをコピーするため、リストの要素を変更すると、参照されているすべてのオブジェクトに影響します。以下のID値から分かります
コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8

obj = ['名前',['年齢',18]]
a=obj[:]
b=リスト(obj)

obj,a,b の x の場合:
id(x[0]),id(x[1])
を印刷します 印刷

a[0] = 'リシ'
b[0] = '張三'

obj,a,b の x の場合:
id(x[0]),id(x[1])
を印刷します 印刷

a[1][1] = 25
b[1][1] = 30

obj,a,b の x の場合:
id(x[0]),id(x[1])
を印刷します 印刷

32564088 34496008
32564088 34496008
32564088 34496008

32564088 34496008
34574704 34496008
33970672 34496008

32564088 34496008
34574704 34496008
33970672 34496008

オブジェクトをコピーすると、すべての要素の ID が同じであることがわかります。a オブジェクトと b オブジェクトの最初の文字列要素をそれぞれ変更しました。文字列は不変オブジェクトであるため、変更は新規作成に相当します。 a と b b の最初の文字列要素 ID が矛盾しています。 a と b の 2 番目の要素は両方ともリスト可変オブジェクトであるため、ID 値が変更されたかどうかに関係なく、ポインターを表し、常に他の参照オブジェクトの値に影響を与えます。
したがって、オブジェクト a の年齢の変更がオブジェクト b の年齢の値に影響する理由、またはオブジェクト b の年齢の値の変更がオブジェクト obj を含むオブジェクト a の年齢の値にも影響するのはなぜですか。

ディープコピー

上記はすべて浅いコピーであるため、コピーされたオブジェクトが独立しており、変更されたときに他の値に影響を与えないことが望まれます。これは深いコピーと呼ばれます。ディープ コピーを実装するには、コピー モジュールを参照する必要があります。コピー モジュールには 2 つの機能があり、1 つはコピー シャロー コピー、もう 1 つはディープコピー ディープ コピーです。

コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8
コピーをインポート
obj = ['名前',['年齢',18]]
a=copy.deepcopy(obj)
b=copy.deepcopy(obj)

a,b の x の場合:
id(x[0]),id(x[1])
を印刷します 印刷

a[1][1] = 25
b[1][1] = 30


を印刷します 印刷 b

33612664 35477256
33612664 35477640

['名前', ['年齢', 25]]
['名前', ['年齢', 30]]

ディープ コピーを使用した後、リスト要素の ID は一貫性がなく、独立したオブジェクトを表します。リスト要素の値を変更しても、他のオブジェクトには影響しません。

コピーする際の注意点は次のとおりです:
まず、非コンテナ型 (数値、文字列、およびコード、型、範囲オブジェクトなどの他の「ヤード」型オブジェクトなど) は、完全なスライス操作を使用してコピーされません。

2 番目に、祖先変数にアトミック タイプのオブジェクトのみが含まれている場合、その変数のディープ コピーは実行されません。
上記の例を Yuanzu に変更して、ディープ コピーを使用してみましょう

コードをコピー コードは次のとおりです:

# エンコーディング=UTF-8
コピーをインポート
obj = ['名前',('年齢',18)]
a=copy.deepcopy(obj)
b=copy.deepcopy(obj)

a,b の x の場合:
id(x),id(x[1])
を印刷します 印刷

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