pythonの秀逸なオブジェクト保存方法の設計
びっくりした話
以下のように記述した際、aとbは全く同じオブジェクト(ここでは2)を指しているらしい。
a = 2 b = 2
全く同じ。英語で言うと"the same object"。色々と疑問が生じたので調べてみた。 まずは、疑問を箇条書きにしてみます。
- 同じところを指してたらaを変更した時に、bも変わっちゃわない?
- てかそれ本当なの?
疑問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
システムの中身のしまわれ方とか見るのも、意外と面白いですね