オブジェクト指向について
Pythonでは数値からモジュールまで全てオブジェクトです。つまり、オブジェクトはPython の核になるものです。
全てのオブジェクトは型(type)を持ちます。型とはつまりそのオブジェクトで何ができるのかを定義したものです。
型にはスカラと非スカラがあります。
スカラとは、よく原子に例えられます。つまり、これ以上分割できないものです。
非スカラは文字列などがあり、内部構造を持ったものです。
Python のスカラオブジェクトは、int, float, bool, None の4つがあります。
オブジェクトの型を確認するにはtype()を使います。この関数は今まで何となく使っていたと思いますが、実はどのようなオブジェクトかを確認していたことになります。
Pythonでは、これらのオブジェクトを意識することなく使用することができます。
オブジェクトの中身がどのようになっているかを気にする必要があるのは、独自のオブジェクトを使うときです。
オブジェクトには属性(変数)とメソッド(関数)が含まれています。そして、これらをまとめたものがクラスです。
クラスについて
Pythonではクラスは単なる型でしかありません。そのためクラスを使おうとするとインスタンス化してオブジェクトを作る必要があります。
インスタンス化して出来上がったオブジェクトの型を調べるとクラス名が返ってきます。つまり、クラスが型を構築していることがわかります。
カプセル化
クラスを作成することで変数と関数をまとめることができます。このことは非常に効率的で便利な仕組みです。なぜなら、humanクラスには人間としての基本的な属性や機能を変数や関数としてまとめることができるからです。foodクラスでは食べ物の基本的な属性や機能がまとめられます。つまり、非常に管理しやすくまとめることができるのです。
そして、さらなる特徴はカプセル化です。カプセル化とは外部に公開する情報を制御できることをいいます。
今回の内容はカプセル化については詳しく言及していませんので、別途解説する予定です。
税込価格を求めるコードの例
税込価格を求める計算を、関数だけで済ませる場合と、クラスを使う場合を考えてみます。
関数だけのコード
# 税込価格を求める関数 rate = 0.1 def tax(total): return int(total * rate) def tax_amount(total): return int(total * (1 + rate)) print('税額{}円'.format(tax(100))) print('税込金額{}円'.format(tax_amount(100)))
結果
税額10円
税込金額110円
クラス作成
クラス名はclassの後に続けて先頭を大文字にした名前をつけます。
クラスの直下に作成した変数をクラス変数と呼びます。変数のことをプロパティという場合もあります。
クラスの中で関数を定義することができます。関数の定義は一般の関数とほとんど同じです。
ただしクラスで定義する関数の第1引数には必ずselfをつける必要があります。
クラスで宣言した関数のことをメソッドと呼びます。
クラス名についてPEP8の命名規則を読んでおくことをお勧めします。
税込価格を求める計算をクラス作成で行う例
- クラス変数を rate = 0.1 で定義
- 税額を求めるメソッド def tax(self,total) を定義
- 支払額を求めるメソッド def tax_amount(self,total)の定義
- メソッドの引数でクラス変数を使う場合はselfが付いていることに注目
税込価格を求めるクラスのコード
# クラス作成 class Rate: rate = 0.1 # クラス変数 def tax(self,total): return int(total * self.rate) def tax_amount(self,total): return int(total * (1 + self.rate))
インスタンス化
クラスが設計図としたならインスタンスは実態になります。 オブジェクト指向でクラスを使う場合には必ず実態化する儀式があります。次の例は上のコードで宣言したRateクラスのインスタンス化の例です。
インスタンス化して税込金額を求める
クラスをインスタンス化することで、様々な具体的なオブジェクトを作ることができます。
例えば、Humanクラスをインスタンス化することで、人間として共通の属性や振る舞いを持った「Tarou」や「Hanako」など様々な人間のオブジェクトを作成することができます。
インスタンス化の例
# インスタンス化 my_rate = Rate() print('税額は',my_rate.tax(100)) print('税込金額は',my_rate.tax_amount(100))
結果
税額は 10
税込金額は 110
クラス変数の使い方
クラス変数は、そのクラスからできる全てのインスタンスで共有される属性やメソッドのためのものです。
クラスにクラス変数を定義しておくと、直接クラスの変数を呼び出すことができます。
クラス変数の呼び出しのコード
# クラス変数の呼び出し方 Rate.rate
結果
0.1
クラス変数の値は外から変更できます。
クラス変数を変更する例
# クラス変数の値を変更できる Rate.rate = 0.08 Rate.rate
結果
0.08
インスタンスの使い方
Personクラスの作成
人間をクラスと考えると、「名前」、「年齢」、「出身地」などの変数を持つことや、「話す」、「歩く」、「寝る」、「食べる」などの関数を持つことも簡単に想像できます。そして、これらの変数と関数を組み立てて行けば良いことになります。
クラスの中の変数を属性やプロパティと呼び、関数のことをメソッドといいます。
selfについて
メソッドの中にあるself という引数はメソッドを呼び出したインスタンスが入ります。
print(‘私の名前は’,self.name,’です。’) の self.name 部分はhideyoshiインスタンスでは hideyoshi.name ということになります。
Person Classの作成例
class Person: name = '名無し' age = 0 born = '不明' def talk(self): print('私の名前は{}です。生まれたのは{}で、年齢は{}です。'.format(self.name,self.born,self.age))
インスタンスの作成
クラスをインスタンス化することで具体的なオブジェクトができます。
Person Classもインスタンス化することで、「ieyasu」インスタンス、「nobunaga」インスタンスのように複数のより具体的な人間が出来上がることになります。
クラス変数がインスタンス変数に変わることもある
次に紹介する動作がPython の変数(属性)でクラス変数とインスタンス変数の区別がつきにくいところです。
インスタンスを作ることで、クラスで作成したクラス変数を変更することができます。
このような変数をインスタンス変数と呼びます。
次の例では、「name」,「age」,「born」がインスタンス変数になります。
変数の前に「ieyasu」,「nobunaga」,「hideyoshi」をそれぞれつけておく必要があります。このようにインスタンス化してできたオブジェクト名を変数の前に付ける事で、グローバル変数のように他の場所で名前が被るなどの問題が起きにくくなります。
ここでのポイントはクラス変数はインスタンス化後の使い方でインスタンス変数に変わることもあるということです。
ただし、この使い方は思わぬトラブルになることもありますのでクラス変数はあくまで全てのインスタンスで共通して使う変数という考え方で使用するようにして、インスタンス変数はクラス変数を使うのではなく後述する方法で定義すべきです。
*サンプルコードの武将の生誕地や年齢は架空の値です。(笑)
ieyasuというインスタンスを作成した例
ieyasu = Person() ieyasu.name = 'Ieyasu' ieyasu.age = 30 ieyasu.born = 'Okazaki' ieyasu.talk() print('class変数の値:', Person.age)
結果
私の名前はIeyasuです。生まれたのはOkazakiで、年齢は30です。
class変数の値: 0
nobunagaというインスタンスを作成した例
nobunaga = Person() nobunaga.name = 'Nobunaga' nobunaga.age = 20 nobunaga.born = 'Nagoya' nobunaga.talk() print('class変数の値:', Person.age)
結果
私の名前はNobunagaです。生まれたのはNagoyaで、年齢は20です。
class変数の値: 0
hideyoshiというインスタンスを作成した例
hideyoshi = Person() hideyoshi.name = 'Hideyoshi' hideyoshi.age = 19 hideyoshi.born = 'Osaka' hideyoshi.talk() print('class変数の値:', Person.age)
結果
私の名前はHideyoshiです。生まれたのはOsakaで、年齢は19です。
class変数の値: 0
クラス変数が使われる例
Personクラスの例では、インスタンス化が行われた際に変数の値を指定しなかった場合、クラス変数を宣言していたらクラス変数の値が使われます。
インスタンス変数を使わなかった例
mituhide = Person() mituhide.talk()
結果
私の名前はです。生まれたのはで、年齢は0です。
クラス変数とインスタンス変数
Pythonのクラス内で宣言する変数には、クラス変数とインスタンス変数があります。
2つの変数の違いは、次のようになっています。
- クラス変数:インスタンスで共通する値(クラス固有の値)を持たせる
- インスタンス変数:インスタンスごとに異なる(インスタンス固有の値)を持たせる
クラス変数はクラス内で宣言します。一方のインスタンス変数はインスタンス化時に宣言することができます。
インスタンス変数は後述のコンストラクタ内で宣言することが一般的です。
クラス変数とインスタンス変数の実例
次のように、変数の定義のないクラスを作成します。
* 変数宣言のないPersonクラスだけれども、メソッドにはnameという変数が使われています。
変数のないクラスの例
class Person: def talk(self): print('私の名前は{}です。'.format(self.name))
上のPersonクラスをインスタンス化して、インスタンス化後に name変数を定義したものが、インスタンス変数になります。
ieyasu = Person() ieyasu.name = 'Ieyasu' ieyasu.talk()
結果
私の名前はIeyasuです。
このように、インスタンス変数はクラスに無い変数をインスタンス後に勝手に作ることができます。
コンストラクタ
コンストラクタはインスタンスを生成すると自動で実行するメソッドです。
コンストラクタは __init__ という名前をつけて引数には必ずself を第1引数に指定します。
インスタンス生成時にインスタンス変数を効率よくまとめて作成したい場合にコンストラクタは役にたちます。
尚、インスタンス変数を使いたい場合には、コンストラクタ内で変数宣言する方法が一番スマートで混乱がない方法です。
class Person: def __init__(self, n, a, b): self.name = n self.age = a self.born = b def talk(self): print('私の名前は',self.name,'です。年齢は',self.age,'で',self.born,'生まれです。')
tokugawa = Person('家康','18','岡崎') tokugawa.talk()
結果
私の名前は 家康 です。年齢は 18 で 岡崎 生まれです。
Pythonのデータ型は全てオブジェクト
Pythonのデータ型は全てオブジェクトです。リストを作成して型を確認すると、class ‘list’と表示されます。
これは、つまりlist クラスということです。
また、Person Classのオブジェクトの型を確認するとクラス名が型になっていることがわかります。
リストの型確認の例
num = [1,2,3,4] print(type(num))
結果
Person Classの型を確認する例
class Person: def __init__(self, n, a, b): self.name = n self.age = a self.born = b def talk(self): print('私の名前は',self.name,'です。年齢は',self.age,'で',self.born,'生まれです。') tokugawa = Person('家康','18','岡崎') type(tokugawa)
結果
__main__.Person
__main__の表記は、現在実行しているPython ファイルで作成されたPersonクラスという意味合いで使われています。
参考になった書籍
プログラミングを少しでも経験がありPython の文法を学習する場合は、「入門 Python 3」が良いと思います。長く使えます。
「退屈なことはPython にやらせよう」はオブジェクト指向の解説がないです。代わりにPythonを使った便利な実例が初心者には嬉しい内容です。正規表現から、簡単なスクレイピング 、画像操作などあります。ただし、中級者以上には少し物足りないかもしれません。
Pythonサンプルのダウンロード
ここでダウンロードする「object1.ipynb」ファイルは、このPython動画で使用したものです。
Python入門一覧
- Python入門 クラスの継承とオーバーライド(動画あり)
- Python入門 オブジェクト指向について、クラスの作り方(動画あり)
- Python入門 lambda関数の使い方、map関数の使い方(動画あり)
- Python入門 位置引数、キーワード引数、デフォルト引数、便利な引数の使い方(動画あり)
- Python入門 グローバル変数とローカル変数(動画あり)
- Python入門 モジュールのインポートとrandomモジュール(動画あり)
- Python入門 関数の定義方法(動画あり)
- Python入門 内包表記(動画あり)
- Python入門 zip関数(動画あり)
- Python入門 for in文の活用(動画あり)
- Python入門 for in文の基本(動画あり)
- Python入門 三項演算子(動画あり)
- Python入門 if文の使い方2 while文の使い方(動画あり)
- Python入門 if文の使い方(動画あり)
- Python入門 浅いコピーと深いコピー(動画あり)
- Python入門 参照渡し(動画あり)
- Python入門 集合(動画あり)
- Python 入門 辞書(動画あり)
- Python 入門 タプルについて(動画あり)
- Python入門 リストのメソッド(動画あり)
- Python入門 リストのスライス(動画あり)
- Python入門 リスト
- Python入門 BMI課題 (動画あり)
- Python入門 文字列の連結とフォーマット1(動画あり)
- Python入門 文字列のフォーマット2(動画あり)
- Python入門 エスケープと型変換とinput()の使い方(動画あり)
- Python入門 pep8(動画あり)
- Python入門 変数の練習(動画あり)
- Python入門 変数(動画あり)
- Python入門 文字列(動画あり)
- Python入門 演算子(動画あり)
- Python入門 Python をはじめよう! (動画あり)