クラスの使い方について詳しく知りたい
メソッドって関数と何が違うの?
この記事を読んでいるPythonプログラミング初心者はクラスという新しい概念の勉強をしていると思います。
クラスは様々なライブラリやフレームワークの実装で使われています。クラスは大規模なプログラムを書くときに非常に重要な概念で、これを使いこなせばプログラミングのしやすさが格段に上がりますよ。
こんにちは!侍エンジニアライターのフクロウです。機械学習のインストラクターをやっています。
この記事ではクラスの勉強をしている入門者向けに、クラスの解説とその使い方を紹介します。気難しい解説は無しにして、コード例とその使い方を紹介します。この記事を読んだ方がすぐにクラスを使い始められるような記事を目指しました。
この記事はこんな人のために書きました
- if/for文、関数を覚えてクラスを学ぼうとしている方
- クラスを使ったコードの書き方が知りたい方
本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。
→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説
なお、その他のPythonの記事についてはこちらにまとめています。
そもそもクラスとは
クラスはデータと専用の関数を持つデータ構造で、これを使うことで型(リストや辞書など)を自分で作ることができます。C言語など別の言語を知っている人向けに説明すると、「クラスとは専用の関数を持つ構造体に近いもの」です。
新しいオブジェクトを作る設計書がクラスであり、クラスから作られた新しいオブジェクトはインスタンスと呼びます。
Pythonでクラスを作ってみよう
実際にコード例を見ながら使い方を見てみましょう。例えば身体測定のデータをクラスで管理することを考えます。
身体測定のデータを一人ひとり別のオブジェクトとして扱うとしましょう。
最も基本的なクラスの書き方と、そこからインスタンスを作る方法は次のようにします。
class クラス名: pass 新しい変数名1 = クラス名() # インスタンス1 新しい変数名2 = クラス名() # インスタンス2
クラスからインスタンス(クラスという設計図をもとに作ったオブジェクト)を作るには、クラス名を関数のように呼び出します。
これを参考に、Personクラスを作ってみましょう。まずは何の機能もない形だけのクラスになります。
class Person: # ①クラスの定義 pass taro = Person() # ②クラスからインスタンスを作成 jiro = Person() print(taro) # ③本当にインスタンスができているか確認 print(jiro)
実行結果:
<__main__.Person object at 0x7fc41046cba8> <__main__.Person object at 0x7fc41046cb70>
このPersonクラスはなんのデータも専用関数も持っていませんが、実際にインスタンスは作成されています。
③のようにして、作ったインスタンスtaroとjiroをprintしてこれらのメモリ番地が表示されることを確認してみてください。
実行結果のように__main__.Person object at 〜と表示されれば成功です!無事にインスタンスが作られています!!
コンストラクタとは?
さて、Personクラスに身体測定のデータをもたせましょう。必要なデータは以下の4つにしましょう。
- 名前
- 年齢
- 身長
- 体重
これらを持つクラスを作るには、インスタンス(クラスという設計書をもとに作られるオブジェクト)を生成する際に呼び出されて、インスタンスにデータを与える事ができる機能(=コンストラクタ)を活用します。
コンストラクタは__init__という名前の関数で定義します。
class Person: # ①コンストラクタの定義 def __init__(self, name, age, shintyo, taiju): self.name = name # ②属性の定義 self.age = age self.height = shintyo self.weight = taiju taro = Person("太郎", 23, 170, 60) # ③ インスタンスの作成 jiro = Person("二郎", 18, 168, 73)
①のコンストラクタの定義を見てみましょう。クラスの中で定義する関数(次の章で紹介しますが、このような関数をメソッドと呼びます。)では、必ず第一引数にselfをおきます。
selfはクラスから作られたインスタンス自体が入ります。
②属性の定義を見てみましょう。これから、インスタンスが持つデータのことを属性と呼ぶことにします。__init__関数の引数をインスタンスの属性に代入するには、self.属性名 = オブジェクト として代入します。
ここで属性名は__init__の引数名と同じにする必要はありません。例えば第四引数のshintyoはself.heightに代入されていますね。
③のインスタンスの作成を見てみましょう。前章とは違い、Personクラスからインスタンスを作るときに引数を渡します。
Personクラスを関数として呼び出すと、__init__メソッドが呼び出されます。このときに、第一引数のselfには自動的に生成されるインスタンス自身が入るので、③のときには第二引数以降をカッコの中に書きましょう。
さて、実際に③で作ったインスタンスの属性がちゃんと値を持っているか確認してみましょう。インスタンスの属性を以下のようにしてprintしてみます。
print("==taroインスタンスの属性==") print(taro.name) print(taro.age) print(taro.height) print(taro.weight) print("==jiroインスタンスの属性==") print(jiro.name) print(jiro.age) print(jiro.height) print(jiro.weight)
実行結果:
==taroインスタンスの属性== 太郎 23 170 60 ==jiroインスタンスの属性== 二郎 18 168 73
同じクラスから作られたにもかかわらず、taroインスタンスとjiroインスタンスは別の属性をもっていることがわかりますね。(成功です!)
メソッドとは?
クラスの中で定義した関数は、そのクラスから作ったインスタンスから実行する事ができます。前の章でも紹介しましたが、このような関数をメソッドと呼びます。
メソッドの中では、普通のように関数の引数を使うことも、インスタンスの属性を使うこともできます。身体測定の結果を使い、BMIを計算してみましょう。
BMIは[体重(kg)]/[身長(m)の2乗]で計算できます。
class Person: def __init__(self, name, age, height, weight): self.name = name self.age = age self.height = height # cm self.weight = weight # kg def bmi(self): hight_m = self.height/100.0 # 身長をメートル単位に修正 return self.weight / hight_m**2.0 # BMIを計算 taro = Person("太郎", 23, 170, 60) jiro = Person("二郎", 18, 168, 73)
先程のPersonクラスにbmiメソッドを追加しました。先ほどと同じようにインスタンスを作成します。
さて、このインスタンスからbmiメソッドを使ってみましょう。
taro_bmi = taro.bmi() jiro_bmi = jiro.bmi() print("太郎のBMI:", taro_bmi ) print("二郎のBMI:", jiro_bmi )
実行結果:
太郎のBMI: 20.761245674740486 二郎のBMI: 25.86451247165533
__init__などの特殊なメソッドを除き、普通のメソッドはインスタンス.メソッド()で呼び出します。(もしもself以外に引数がある場合は、このときに引数を渡します。)
実際に[Output]を見てみるとBMIがちゃんと計算できていることがわかりますね。このようにしてメソッドを定義して、実際に使うことができるわけです。
まとめ
この記事では、Python入門者向けにクラスの使い方を紹介しました。
メソッドやインスタンス、コンストラクタという付随する専門用語がたくさん出てきましたが、これらを使いこなすことでただの関数だけでは実装が難しいような大きなプログラムを作成する事ができます。
多くの有名なライブラリもクラスをもとに書かれいるので、様々な教材が世の中に溢れていると言えます。この記事での勉強が終わったら、是非ともGithubなどでPythonのライブラリを検索してみてください。クラスを使ったコーディングの利点が更に実感できるでしょう。