0

これらの 2 つのクラス定義は同じように構造化されていますが、bright() クラス定義では属性 'd' がリストであり、normal() クラス定義では int です。奇妙な()クラスがself.d = dになる理由がわかりませんが、クラスnormal()には当てはまりません。この状況で Python が int と list を別々に扱うのはなぜですか?

class weird:
    def __init__(self):
        d = [1,2,3]
        self.d = d
        for x in range(3):
            d[x] = 10+x 
        print "d =", d
        print "self.d =", self.d

class normal:
    def __init__(self):
        d = 1
        self.d = d
        d = 11
        print "d =", d
        print "self.d =", self.d

コードを実行すると、

>>> a=weird()
d = [10, 11, 12]
self.d = [10, 11, 12]
>>> b=normal()
d = 11
self.d = 1
4

4 に答える 4

7

代入とオブジェクトの突然変異を混同しています。

1 つの方法では、新しい値を に割り当てd、それが指すものを変更しました。

d = 11

しかし、他の方法では、に含まれる値を変更しましたd:

d[x] = 10 + x

そこに注意してください[x]。あなたは、本質的に、Pythonにこれを行うように指示しています:

d.__setitem__(x, 10 + x)

dリストを指す変数 の値は決して変更されません。によって参照されるリストの値dは変更されます。

この以前の私の回答を見てください。これは、これら 2 つのステートメントの違いについて詳しく説明しています: Python list does not Reflect variable change

于 2012-12-17T17:20:12.063 に答える
2

実際、言語はここで完全に一貫しています。2 つの基本的に異なる操作を実行しているため、2 つの異なる動作が観察されます。

の最初の 2 行は__init__、両方のクラスで一貫しています (異なるタイプの を除くd)。

class WeirdOrNormal:
    def __init__(self):
        d = ... # 1 or [1, 2, 3]
        self.d = d

この時点で、両方とも同じオブジェクトdを参照します。self.d

ただし、その後、2 つのクラスは分岐します。

  1. weird参照を通じてオブジェクトを変更します。

    for x in range(3):
        d[x] = 10+x 
    

    dと は同じオブジェクトを参照しているため、両方self.dから変更を確認できます。

  2. normald以外の場所を指すように再バインドしますself.d:

    d = 11
    

    dこれにより、との間のリンクが切れましたself.d。彼らは今、完全に独立しています。

weird参照も再バインドするように変更するnormalと、2 つのクラスが互いに一貫して動作することがわかります。

class notweird:
    def __init__(self):
        d = [1,2,3]
        self.d = d
        d = [10+x for x in self.d]
        print "d =", d
        print "self.d =", self.d

a = notweird()

これは印刷します

d = [11, 12, 13]
self.d = [1, 2, 3]
于 2012-12-17T17:23:50.713 に答える
1

ドキュメントの場合:

値が変化する可能性のあるオブジェクトは可変であると言われます。作成後に値を変更できないオブジェクトは、不変と呼ばれます。(変更可能なオブジェクトへの参照を含む不変のコンテナー オブジェクトの値は、後者の値が変更されると変更される可能性があります。ただし、コンテナーに含まれるオブジェクトのコレクションは変更できないため、コンテナーは依然として不変と見なされます。したがって、不変性は厳密には異なります。変更不可能な値を持つのと同じですが、より微妙です。) オブジェクトの可変性はその型によって決まります。たとえば、数値、文字列、タプルは不変ですが、辞書とリストは変更可能です。

あなたの場合list、可変でintあり、不変です。奇妙なことは何もありません。

データモデルの詳細。

于 2012-12-17T17:16:19.397 に答える
0

最初の例では、 と の両方が可変オブジェクトdself.d指しています。オブジェクトの要素に 10 を追加すると、その変更可能なオブジェクトが変更されます。との両方がそのオブジェクトdself.d指しているため、どちらも結果を「見る」ことができます。

2 番目の例では、d を再割り当てして、別の不変の数値を指すようにします。したがってd、 とself.dは 2 つの異なるものを指します。

違いに注意してください。一方のケースでは、両方とも変更する同じ値を指しており、もう一方のケースでは、2 つの異なる値を指しています。

于 2012-12-17T17:17:30.267 に答える