Python: 変数(variable)と参照とコピーの備忘録

Python

list、dictionary、setの参照と各種copyに関して書きながら改めて理解した事の備忘録。

immutableなオブジェクトの参照

下記の変数(variable)aに1を代入する行為で何が起きているのか。

>>> a = 1
>>> b = a

ここで行われているのは下記3つの行為

  1. int型オブジェクト”1″を作る
  2. オブジェクト”1″に aという名前を付ける(参照)
  3. 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つの行為

  1. list型オブジェクト”[1, 2, 3, 4]”を作る
  2. オブジェクト”[1, 2, 3, 4]”に cという名前を付ける(参照)
  3. 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)が準備されていると言う理解。

コメント

タイトルとURLをコピーしました