インターンについてはすでに説明したので、可変/不変のものだけを扱います。
イミュータブルを変数に代入します。
実際に起こっていることについて話すとき、私はこの言葉遣いを選びません。
オブジェクト (メモリに存在するもの) と、それらのオブジェクトにアクセスする手段があります: 名前 (または変数)。これらは参照内のオブジェクトに「バインド」されています。(オブジェクトのポイントを言うことができます)
名前/変数は互いに独立しており、たまたま同じオブジェクトにバインドされることも、異なるオブジェクトにバインドされることもあります。そのような変数の 1 つを再配置しても、他の変数には影響しません。
値渡しや参照渡しというものはありません。Python では、常に「オブジェクトごと」に渡したり割り当てたりします。変数を関数に割り当てたり渡したりするとき、Python はコピーを作成することはなく、常に、既に持っているものとまったく同じオブジェクトを渡したり割り当てたりします。
さて、不変オブジェクトを変更しようとするとどうなるでしょうか? 既に述べたように、オブジェクトは不変であるため、代わりに次のようになります: Python は変更されたコピーを作成します。
あなたの例については:
a = 10
b = a
a =20
print (b) #b still is 10
これは可変性とは関係ありません。最初の行で、int オブジェクトを値とともに10
name にバインドしますa
。2 行目では、 によって参照されるオブジェクトをa
nameにバインドしますb
。
3 行目では、int オブジェクトを値とともに20
namea
にバインドしますが、名前のバインド先は変更されませんb
!
この場合、a は b への参照ではなく、b のコピーを参照します。b が変更可能な場合、a は b への参照になります
既に述べたように、 Python には参照のようなものはありません。Python の名前はオブジェクトにバインドされています。異なる名前 (または変数) をまったく同じオブジェクトにバインドできますが、異なる名前自体の間には関係がありません。物事を変更すると、オブジェクトが変更されます。そのため、そのオブジェクトにバインドされている他のすべての名前は「変更を確認」されます。変更したのと同じオブジェクトにバインドされていますよね?
名前を別のオブジェクトにバインドすると、それが起こります。他の名前には魔法はかけられていません。そのままの状態のままです。
リストの例については:
In [1]: smalllist = [0, 1, 2]
In [2]: biglist = [smalllist]
In [3]: biglist
Out[3]: [[0, 1, 2]]
In[1] と In[2] の代わりに、次のように書いたかもしれません。
In [1]: biglist = [[0, 1, 2]]
In [2]: smalllist = biglist[0]
これは同等です。
ここで重要なことは、biglist が 1 つの項目を持つリストであることです。この一品はもちろんオブジェ。それがリストであるという事実は、何らかの魔法を思い起こさせるものではありません。たまたまリストになっている単純なオブジェクトに名前を付けただけsmalllist
です。
したがって、biglist[i] へのアクセスは、smalllist へのアクセスとまったく同じです。これらは同じオブジェクトだからです。コピーは作成せず、オブジェクトを渡しました。
In [14]: smalllist is biglist[0]
Out[14]: True
リストは可変であるため、smallist を変更して、その変更が biglist に反映されるのを確認できます。なんで?smallist が参照するオブジェクトを実際に変更したためです。まだ同じオブジェクトがあります (変更されているという事実は別として)。しかし、biglist は最初の項目として同じオブジェクトを参照するため、その変更を「認識」します。
In [4]: smalllist[0] = 3
In [5]: biglist
Out[5]: [[3, 1, 2]]
リストを「倍増」する場合も同様です。
In [11]: biglist *= 2
In [12]: biglist
Out[12]: [[0, 1, 2], [0, 1, 2]]
何が起こるか: リストがあります: [object1, object2, object3] (これは一般的な例です) 得られるもの: [object1, object2, object3, object1, object2, object3 ] : "biglist") リストの末尾にあるすべてのアイテム。繰り返しますが、オブジェクトを挿入しますが、魔法のようにコピーを作成するわけではありません。
したがって、biglist の最初の項目内の項目を変更すると、次のようになります。
In [20]: biglist[0][0]=3
In [21]: biglist
Out[21]: [[3, 1, 2], [3, 1, 2]]
smalllist
すべての意図と目的のために、次のbiglist
ように表すことができるため、を変更することもできます。 [smalllist, smalllist]
-- まったく同じオブジェクトが 2 回含まれています。