1

あるセクションで、著者は自己矛盾を示す 2 つの文章を書いています。

最初の1つ:

A shallow copy of an object is defined to be a newly created object of the same 
type as the original object whose contents are references to the elements in the 
original object. 

2番目のもの:

when shallow copies are made, the string is explicitly copied and a new (string) 
object created 

最初の文は、浅いコピー時に文字列オブジェクトとリスト オブジェクトがすべて参照 (明示的にコピーされていない) であることを意味します。

2 番目の文は、浅いコピー時に文字列オブジェクトが明示的にコピーされることを意味します。

最初の一文が正しいと思います。2番目は次のようにする必要があると思います:

when "wifey[0] = 'jane'" is executed, the string is explicitly copied and a new 
(string) object created 

作者がなぜ2番目のものを書いたのか、私にはわかりません。私は正しいですか?

これは資料全体です:

6.20。*Python オブジェクトのコピーと浅いコピーと深いコピー

セクション 3.5 の前半で、オブジェクト割り当てが単なるオブジェクト参照であると説明しました。つまり、オブジェクトを作成してからそのオブジェクトを別の変数に代入すると、Python はオブジェクトをコピーしません。代わりに、オブジェクトへの参照のみをコピーします。

たとえば、若いカップルの一般的なプロファイルを作成するとします。人と呼ぶ。次に、このオブジェクトを両方にコピーします。以下の例では、オブジェクトをコピーする 2 つの方法を示します。1 つはスライスを使用し、もう 1 つはファクトリ関数を使用します。関連のない 3 つのオブジェクトがあることを示すために、id() 組み込み関数を使用して、各オブジェクトの ID を示します。( is 演算子を使用して同じことを行うこともできます。)

>>> person = ['name', ['savings', 100.00]]
>>> hubby = person[:]       # slice copy
>>> wifey = list(person)    # fac func copy
>>> [id(x) for x in person, hubby, wifey]
[11826320, 12223552, 11850936]

個人の普通預金口座が作成され、最初の 100 ドルのデポジットが含まれます。名前は、各人のオブジェクトをカスタマイズするために変更されます。しかし、夫が 50.00 ドルを引き出すと、別のコピーが作成されたにもかかわらず、夫の行動が妻の口座に影響を与えました。(もちろん、これは、単一の共同アカウントではなく、個別のアカウントを持つことを前提としています。) それはなぜですか?

>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> hubby, wifey
(['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 50.0]])

その理由は、浅いコピーしか作成していないためです。オブジェクトの浅いコピーは、コンテンツが元のオブジェクトの要素への参照である元のオブジェクトと同じ型の新しく作成されたオブジェクトであると定義されます。つまり、コピーされたオブジェクト自体は新しいですが、内容はそうではありません。シーケンス オブジェクトの浅いコピーはデフォルトのコピー タイプであり、さまざまな方法で作成できます。など、または (3) copy モジュールの copy() 関数を使用します。

次の質問は次のとおりです。妻の名前が割り当てられたとき、なぜそれが夫の名前に影響しなかったのですか? 二人とも「ジェーン」という名前を付けるべきではありませんか? それが機能し、名前が重複していない理由は、それぞれのリストに 2 つのオブジェクトが含まれているためです。1 つ目は不変 (文字列) で、2 つ目は可変 (リスト) です。このため、浅いコピーが作成されると、文字列が明示的にコピーされ、新しい (文字列) オブジェクトが作成されます。リストには参照のみがコピーされ、メンバーはコピーされません。したがって、名前を変更することは問題ではありませんが、銀行情報の一部を変更することは問題です. ここで、各リストの要素のオブジェクト ID を見てみましょう。銀行オブジェクトはまったく同じであり、一方を変更すると他方が影響を受けることに注意してください。名前を変更した後、元の「名前」文字列が新しい名前文字列に置き換えられることに注意してください。

前:

>>> [id(x) for x in hubby]
[9919616, 11826320]
>>> [id(x) for x in wifey]
[9919616, 11826320]

後:

>>> [id(x) for x in hubby]
[12092832, 11826320]
>>> [id(x) for x in wifey]
[12191712, 11826320]
4

1 に答える 1