14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pythonで、無駄がなく、すごく省エネなオブジェクトの保存方法にびっくりした話

Last updated at Posted at 2016-01-26

びっくりした話

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

a = 2
b = 2

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

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

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

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

簡単にまとめると、

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

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

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

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

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

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

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

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

test.py

a = 2
b = 2

id(a) #4401166416

id(b) #4401166416

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

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

まだ疑い深いKanChinは新しくc=3を定義して、もう一回実験をしてみた。

test.py
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さんからコメントにて訂正を頂きました。

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

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

test

d = 50000
e = 50000

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

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


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

14
14
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?