ゆーかん

徒然日記

pythonの秀逸なオブジェクト保存方法の設計

びっくりした話

以下のように記述した際、aとbは全く同じオブジェクト(ここでは2)を指しているらしい。

a = 2
b = 2

全く同じ。英語で言うと"the same object"。色々と疑問が生じたので調べてみた。 まずは、疑問を箇条書きにしてみます。

  1. 同じところを指してたらaを変更した時に、bも変わっちゃわない?
  2. てかそれ本当なの?

疑問1:書き変わらない?

これはよく考えれば、一個前の記事で調べてた内容でした。

簡単にまとめると、

全く同じオブジェクトが既に存在している場合には、
メモリの節約のために、その同じオブジェクト参照する。

同じオブジェクトが存在しなければ、新しく作成される。

つまり、a=3と新しく入力された場合、新規にオブジェクトを作成する。そして、b=2はそのまま保存される、というところでしょうか。

もちろん初心者のメモ書きなので、根本的な部分ではもっと複雑なことが起こってるのでしょうが、この定義でも矛盾なく説明できるので、とりあえずこのまま進んでみます。

疑問2:本当かどうか確かめる(id関数の使用)

本当かどうか確かめるために、メモリ空間のアドレスと言われるものを直接見られるid関数を使って見る。

id() について調べてみると分かるのですが、どうやら識別値を戻り値とするようです。つまり、同じオブジェクトを指していれば、戻り値は同じで、違うものであれば、戻り値も違うってことですね。

では、本題の本当に一緒のものなのかを調べていきます。

a = 2
b = 2

id(a) #4401166416

id(b) #4401166416

id(a) == id(b) #True 数字を見るのが面倒なので==使ってみた。

どうやら本当らしい。つまり、オブジェクトが新しく生成される時のルールは以下の通りになっているんだろう。

c=3を定義して、もう一回実験をしてみた。

c = 3 

id(c) #4401166448

id(a) == id(c) #False 

#この後、aを3に書き換えてcと同じになるか確かめる。

a = 3

id(a) #4401166448

id(a) == id(c) #True

と見事一緒になりました。つまり、

同一のオブジェクトが存在してれば、
新しいオブジェクトは作られない。

みたいですね。(※追記にて、一部訂正あり)

何の役に立つかわからないけど、内容的には不思議で面白いですねぇ

追記

yubaさんより

このような設計手法のことをFlyweightパターンと呼びます(メモリ消費が軽くなるから「フライ級」です)。ご参考に。

とのことです。ありがとうございます。

shiracamusさんからコメントにて訂正を頂きました。

どうやら大きな値である場合には、値が全く同じオブジェクトであっても、新しいオブジェクトは作られるみたいです。

てことで実行してみたのがこちら。

d = 50000
e = 50000

id(d) #4406088592
id(e) #4404350832

id(d) == id(e) #False

システムの中身のしまわれ方とか見るのも、意外と面白いですね

元記事:pythonでの、変数の処理について詳しく調べてみた