list、dictionary、setの参照と各種copyに関して書きながら改めて理解した事の備忘録。
immutableなオブジェクトの参照
下記の変数(variable)aに1を代入する行為で何が起きているのか。
>>> a = 1 >>> b = a
ここで行われているのは下記3つの行為
- int型オブジェクト”1″を作る
- オブジェクト”1″に aという名前を付ける(参照)
- aを通してオブジェクト”1″にbと言う名前も付ける(参照)
オブジェクトを作る
まず、”1″と言うint型のオブジェクトをメモリ上に作る。
オブジェクトに名前をつける
そして、そのint型オブジェクト”1″にaという名前を付ける。これが”=”であり、参照。
だから、aで1が出力される。
オブジェクトにもう一つ名前をつける
次に、int型オブジェクト”1″にaを通してもう一つbと言う名前を付ける。これがb = a。
bを出力しようとすると、aと一緒に参照している”1″を出力する。
参照先がimmutableなら話はそこで終わり
このa、bが参照しているint型オブジェクト”1″はimmutable(不可変)なデータ。
よってa、bが他のものを参照するまで、変わらないint型オブジェクト”1″を参照するa = 1 = bの関係は変わらない。
今回のint型”1″の様に、”=”で参照していても、variable “a”, “b”が参照しているオブジェクト”1″それ自体はimmutable(不可変)であり、そこで終了。
参照と浅いコピー(Shallow copy)に違いはない。
mutableなオブジェクトの参照
参照先がmutableだった場合に問題になる
問題はaが list、dictinary、set等のmutable(可変)データだった場合。
>>> c = [1, 2, 3, 4] >>> d = c
ここでも行われているのは下記3つの行為
- list型オブジェクト”[1, 2, 3, 4]”を作る
- オブジェクト”[1, 2, 3, 4]”に cという名前を付ける(参照)
- cを通してオブジェクト”[1, 2, 3, 4]”にdと言う名前も付ける(参照)
先程と異なり、参照先のlist型オブジェクトがmutableなので、参照先のlistを変更すると、c, dが参照している先のlist型オブジェクトの中身が変わる。
>>> c[1] = 10 >>> c [1, 10, 3, 4] >>> d [1, 10, 3, 4]
immutable かmutableかが問題
以上見てきた様に、参照はimmutableなオブジェクトを参照するのか、mutableなオブジェクトを参照するかで挙動が変わってくる。
これを防ぐ為にmutableなオブジェクトを参照している場合に浅いコピー(Shallow copy)、深いコピー(Deep copy)が準備されていると言う理解。
コメント