14

David Beazley による「Python Essential Reference」の p.35 で、彼は最初に次のように述べています。

文字列などの不変データの場合、インタープリターはプログラムのさまざまな部分間でオブジェクトを積極的に共有します。

ただし、同じページの後半で、彼は次のように述べています。

数値や文字列などの不変オブジェクトの場合、この割り当てによって効果的にコピーが作成されます。

しかし、これは矛盾していませんか?一方で彼はそれらが共有されていると言っていますが、一方で彼はそれらがコピーされていると言っています。

4

3 に答える 3

10

Python での割り当てでは、コピーが作成されることはありません (技術的には、クラス メンバーの割り当てが__setattr__、プロパティ、または記述子を使用して再定義された場合にのみ可能です)。

だから後

a = foo()
b = a

返されたものはfooコピーされておらず、代わりに 2 つの変数があり、同じオブジェクトab指しています。オブジェクトが不変かどうかは関係ありません。

aただし、不変オブジェクトの場合、これが事実であるかどうかを判断するのは困難です (1 つの変数を使用してオブジェクトを変更し、別の変数を使用して変更が表示されるかどうかを確認することはできないため) b

一部の不変オブジェクトについても、Python は新しいオブジェクトを作成する代わりに古いオブジェクトを自由に再利用できます。

a = x + y
b = x + y

xとの両方yが数値である場合 (合計は数値であり、不変です)、 と の両方が同じオブジェクトを指している可能性がありaますb。そのような保証はないことに注意してください...代わりに、同じ値を持つ異なるオブジェクトを指している可能性もあります。

覚えておくべき重要なことは、egcopyまたはdeepcopy. これは、変更可能なオブジェクトで驚きを避けるために非常に重要です。

たとえば、よくあるイディオムは次のとおりです。

class Polygon:
    def __init__(self, pts):
        self.pts = pts[:]
    ...

この場合、オブジェクトの作成後にコンストラクタに渡されたリストに変更が適用された場合に、ポイント リストが予期せず変更されないようにするために、ポイントの配列全体のコピーを作成するself.pts = pts[:]代わりに使用されます。self.pts = pts

于 2012-07-20T19:57:54.330 に答える
6

効果的にコピーを作成します。実際にはコピーを作成しません。2 つのコピーを持つことと、2 つの名前が同じ値を共有することの主な違いは、後者の場合、一方の名前による変更が他方の名前の値に影響することです。値を変更できない場合、この違いはなくなります。そのため、不変オブジェクトの場合、値がコピーされるかどうかに実質的な影響はほとんどありません。

id不変型 (例えば、関数や演算子を使用することによって) でもコピーと異なるオブジェクトの違いを見分けることができるいくつかのまれなケースがありますがis、これらは Python 組み込みの不変型 (文字列や数値など) には役に立ちません。

于 2012-07-20T19:39:58.870 に答える