Pythonプログラミング(ステップ8・クラスとオブジェクト・その2)
このページでは、オブジェクトの操作方法や注意点について学ぼう。
1.オブジェクトの実体と参照
Pythonのオブジェクトは、データと手続きが格納された「箱」(パッケージ)のようなものである。 そして、オブジェクトは、クラスの定義にしたがって生成できる。 ここで、変数とオブジェクトの関係には注意が必要である。 例えば、
# coding: utf-8 class Person: def __init__(self,name): self.name=name # メイン部 s1 = Person("木村") s2 = s1
のようなコードを実行すると、実際に変数s1
にセットされるのは、「木村」オブジェクトの参照先(箱の場所)である。
よって、代入操作 s2=s1
によって s2
にコピーされるのは場所情報のほうであって、オブジェクトの実体が複製されるわけではない。その様子を図示すると、以下のとおりである。
copyモジュールを使う際は、
import copy
を忘れずに
オブジェクトのコピーを新たに作成したい場合は、copyモジュールを使って、以下のようにする。
# coding: utf-8 import copy class Person: def __init__(self,name): self.name=name # メイン部 s1 = Person("木村") s2 = copy.copy(s1)
このコードを実行すると、変数の参照関係は以下のようになる:
練習:リストオブジェクト
以下は、[1,2,3,4,5]の置換をすべて求め、プリントするコードの例である。
コードの中で q = copy.copy(p)
としている箇所を、単に代入 q=p
変更すると、正しく動作しない。
この記述法は「リスト内包表記」と呼ばれる
また、コードの途中で
y = [b for b in x if b != a]
とあるが、これは『リスト x の要素の中で a に等しくないものを取り出して、新しいリストを作成し、yにセットする』を意味する。
この箇所を y = x.remove(a)
(『xからaを削除してyに代入』)に変更しても、コードは正しく動作しない。
実際にコードを実行して確かめながら、理由を考えてみなさい。
# coding: utf-8 import copy def permutation(p,x): if len(x)<1: print(p) return else: for a in x: q = copy.copy(p) # 【注目箇所その1】 q.append(a) y = [b for b in x if b != a] # 【注目箇所その2】 permutation(q,y) return # メイン部 permutation([],[1,2,3,4,5])
ヒント
Pythonでは、リスト(配列)を含めて、基本的にすべてのデータはオブジェクトとして扱われている。
2.オブジェクトID
沢山のオブジェクトが混在するようなコードを記述する際、参照先のオブジェクトが同一のものかどうかの確認が必要となる場合がある。
オブジェクトにはそれぞれにユニークな番号(id)が付番されており、id( )
関数
id(オブジェクトを参照している変数名)
によってidを知ることができる。例えば、このページの最初の例に、オブジェクトidをプリントするコードを追加して、
# coding: utf-8 class Person: def __init__(self,name): self.name=name # メイン部 s1 = Person("木村") s2 = s1 print(id(s1)) print(id(s2))
を実行すると、全く同じ数値がプリントされる。であるから、idの値を比較することによって、実体が同じかどうかを判定できる。例えば、
if id(s1) == id(s2): print("同一のオブジェクトです") else: print("異なるオブジェクトです")
is
演算子の否定形はis not
しかしながら、通常、オブジェクトの比較は is
演算子で行う:
if s1 is s2: print("同一のオブジェクトです") else: print("異なるオブジェクトです")
上記の2つのコードは同じ結果を与える。
練習:オブジェクトidの確認
Pythonでは、数値や文字列などの基本的なデータ、TrueやFalse、None等もすべてオブジェクトとして扱われる。
import math i = 1 j = 1 x = math.sqrt(2) y = math.sqrt(2) s = "abc" t = "abc"
のように変数に値を代入して、オブジェクトidがどのように設定されるのか、確認しなさい。
ヒント
数値、文字列、そして、真偽を表すTrue
やFalse
、
ヌル(空)を表すNone
も、オブジェクトの一種である。
こうした、あらかじめ定義されているオブジェクトの多くは、その実体は「ひとつ」である。