ホームページ  >  記事  >  バックエンド開発  >  Python のコピー モジュール (浅いコピーと深いコピー) についての深い理解

Python のコピー モジュール (浅いコピーと深いコピー) についての深い理解

高洛峰
高洛峰オリジナル
2017-03-28 17:16:321851ブラウズ

主にPythonのcopyモジュールを紹介します。

コピー モジュールには、リスト、タプル、辞書、ユーザー定義オブジェクトのインスタンスなどの複合オブジェクトの深いコピーと浅いコピーを作成する関数が含まれています。

########

copy(x)

########

新しい複合オブジェクトを作成し、x のメンバーを参照によってコピーして、x の浅いコピーを作成します。もっと深く言えば、

オブジェクトをコピーしますが、オブジェクト内の要素の参照は引き続き使用されます。

組み込み型の場合、この関数はあまり使用されません。

代わりに、list(x)、dict(x)、set(x) などの呼び出しメソッドを使用して、x の浅いコピーを作成します

のように型名を直接使用するのは明らかに手間がかかることを知っておく必要があります。 copy() を使用するよりも高速です。しかし、それらは同じ効果をもたらします。

もう 1 つのポイントは、変更できないオブジェクト (文字列、数値、タプル) です。これらのオブジェクトの変更について心配する必要はありません。コピーしてもしなくても意味はありません。

もう 1 つのポイントは、is 演算子を使用して、オブジェクトがコピーされるかどうかを決定することができます。

a は b -> True a と b はコピーではなく同じオブジェクトを参照します

- -> False a と b は互いのコピーです

たとえば、次の例では:

( 1)

>>> a = [1,2,3]

>>> b = copy.copy(a)

>>> , 3]

>>> a.append(4)

>>> a

[1, 2, 3, 4]

>>> , 2, 3 ]

>>> a は b

(2)

>>> a = [1,2,3]

> = a

>>> b

[1, 2, 3]

>>> a.append(4)

>>> 3, 4]

>>> b

>>> b.append(6)

>>>

([1, 2, 3, 4, 6], [1, 2, 3, 4, 6])

(3)

>>> a = [1,2,3]

>> > b = リスト(a)

>>> b

[1, 2, 3]

>>> > a

[1, 2, 3, 4]

>>> = [[1], ['a'], ['A']]

>>> copy.copy(a)

>>> print a, b

[[ 1], ['a'], ['A']] [[1], ['a'], [' A']]

>>> b[1].append('b' )

>>> b

[[1], ['a', 'b'], [ 'A']]

>>> a

[[1], [ 'a', 'b'], ['A']]

>>> 100,101])

>>> b

[[1], ['a ', 'b'], ['A'], [100, 101]]

>

[[1], ['a', 'b'], ['A'] ]

例 (3) では、a の浅いコピー オブジェクト b がわかります。これらは異なるオブジェクトであるため、変更されます。オブジェクトへの影響は互いにありませんが、これらの a と b のオブジェクトの要素は参照が同じであるため、a または b がそのオブジェクトの要素を変更すると、影響を受けます

もう一方の値。

オブジェクトとオブジェクトのすべての要素の値を完全にコピーしたい場合は、以下の deepcopy() 関数のみを使用してください。

######################

deepcopy(x[, visit])

############ # #########

新しい複合オブジェクトを作成し、x のすべてのメンバーを繰り返しコピーすることで、x のディープ コピーを作成します。

visit は、訪問されたオブジェクトを追跡することを目的としたオプションの辞書であり、それによって

を定義するデータ構造内の繰り返しサイクルを検出して回避します。

通常は必要ありませんが、メソッド __copy__(self) と __deepcopy__(self, visit) を実装することで、

クラスはカスタム コピー メソッドをそれぞれ実装できます。

__deepcopy__() メソッドは、コピー プロセス中に以前に遭遇したオブジェクトを追跡するために辞書訪問を使用する必要があります。

__deepcopy__() メソッドの場合、実装に含まれる他の deepcopy() メソッド (存在する場合) にアクセスを渡す以外の操作を実行する必要はありません。

pickle モジュールで使用されるメソッド __getstate__() および __setstate__() をクラスが実装している場合、コピー モジュールはこれらのメソッドを使用してコピーを作成します

ただし、メソッド __copy__(self) と __deepcopy__(self, visit) を実装することで、

クラスはカスタム コピー メソッドをそれぞれ実装できます。

__deepcopy__() メソッドは、コピー プロセス中に以前に遭遇したオブジェクトを追跡するために辞書訪問を使用する必要があります。

__deepcopy__() メソッドの場合、実装に含まれる他の deepcopy() メソッド (存在する場合) にアクセスを渡す以外の操作を実行する必要はありません。

pickle モジュールで使用されるメソッド __getstate__() および __setstate__() をクラスが実装している場合、コピー モジュールはこれらのメソッドを使用してコピーを作成します

。ですが、メソッド __copy__(self) と __deepcopy__(self, visit) を実装することで、

クラスはカスタム コピー メソッドをそれぞれ実装できます。

__deepcopy__() メソッドは、コピー プロセス中に以前に遭遇したオブジェクトを追跡するために辞書訪問を使用する必要があります。

__deepcopy__() メソッドの場合、実装に含まれる他の deepcopy() メソッド (存在する場合) にアクセスを渡す以外の操作を実行する必要はありません。

pickle モジュールで使用されるメソッド __getstate__() および __setstate__() をクラスが実装している場合、コピー モジュールはこれらのメソッドを使用してコピーを作成します

例:

>>> a = [[1], ['a'], ['A']]

>>> b = copy.deepcopy(a)

>>> b

[[1], ['a'], ['A']]

>>> c = copy.copy(a )

>>> c

[[1], ['a'], ['A']]

>>> a[1].append('b')

>>> a

[[1], ['a', 'b'], ['A']]

>>> b

[[1], ['a' ], ['A']]

>>> c

[[1], ['a', 'b'], ['A']]

次のことに注意してください:

( 1) copy モジュールは整数や文字列などの単純な型に使用されますが、これが必要になることはほとんどありません。

(2) これらのコピー関数は、モジュール、クラス オブジェクト、関数、メソッド、トレースバック、スタック フレーム、ファイル、ソケット、およびその他の同様のタイプでは機能しません。

オブジェクトをコピーできない場合は、copy.error 例外が発生します。

以上がPython のコピー モジュール (浅いコピーと深いコピー) についての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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