問題
pythonのクラスが難しい。自分のためにまとめてみることにした。
あらかじめ記載しておきますが、初学者視点で自分の頭で理解できるようにまとめたものです。認識の違いや、理解の甘さ等、多々あると思いますが、あくまで自分のイメージの話です。しっくり来たのでまとめさせてもらいました。ご了承ください。
よく言われる設計書
クラスの説明があるとき、必ずといっていいほど言われることが「クラスは設計書、インスタンスが製品」。
言っていることはなんとなくわかるが、いまいちしっくりこない。
言い換えてみた
そもそも製品をつくるため(返り値をもらうため)にクラスを設定している。そして、「クラスは工場。インスタンスは部品セット」と考えることにした
イメージ
工場(クラス)➝この変数を与えたら、この部署(メソッド)を使ってこのような結果を返します。
部品セット(インスタンス)➝工場(クラス)に値を与えれば、製品ができあがる。
【下図①〜⑤のイメージ】
このようにイメージすると理解が進んだ。
理解を深める
上図と合わせて読み進めてもらいたい。例題をもとに説明を行っていく。
例題
class Dog:
def __init__(self, name):
self.name = name
def parts(self):
print(f'my name is {self.name}')
dog1 = Dog(name='ポチ')
dog1.parts()
#結果
#my name is ポチ
インスタンス(部品セット)
どの説明をみても大抵はクラスから説明が入るが、自分なりにインスタンスから説明したほうが理解しやすいと感じたため、インスタンスから説明する。
まず、クラス(工場)を確認する。
そうすると以下のように記述してある。
class Dog:
def __init__(self, name):
self.name = name
「selfのほかに「name」が定義されているな。つまり「name」という値がほしいんだな。」と認識する。※そういうもんだ、と憶える。selfについては後述。
では、nameを与えてあげよう。ということになるのでインスタンス(部品セット)を作成する。
#インスタンス名 = クラス名(欲しがっている変数 = 値)
dog1 = Dog(name='ポチ')
これでdog1というインスタンス(部品セット)が出来上がった。
部品セット(インスタンス)を使って、製品を作りた(返り値がほし)かったら、
#インスタンス名.使いたいメソッド()
dog1.parts()
#結果
#my name is ポチ
により、クラス(工場)に与えたインスタンス(部品セット)で画面に出力される(製品ができあがる)
クラス(工場)
以下のように定義する
class クラス名
def __init__(self, name):
self.name = name
このとき、クラス(工場)には以下の特別なルールがある。
① __init__
を作成する
②メソッドの第一引数にはselfを記述する
順番に見ていく
① def __init__
を作成する
def __init__とは、初期化する部署。ここに書かれたことはインスタンスごとに設定されることになる。※「さまざまなデータ入り乱れたら嫌だよね。だから、与えられたら初期化しよう」ということ
つまり、今回の例で行くと
class Dog:
def __init__(self, name):
self.name = name
dog1 = Dog(name='ポチ')
dog1というインスタンス(部品セット)があって、Dogというクラスにname=ポチという部品が与えている。ポチという値が、まずは__init__メソッド(初期化部署)にて定義されている。
②メソッドの第一引数にはselfを記述する
クラス(工場)にインスタンス(部品セット)が送られてくる。この場合はname='ポチ'が送られてくる。自動的に__init__メソッド(初期化部署)にて定義される。そして、__init__メソッドから、各メソッド(部署)に部品を回して、製品を作っていくわけである。しかし、場合によっては、数十個ものインスタンス(部品セット)が送られてくるため、どの部品がどのインスタンス(部品セット)だったかわからなくなってくる。それを回避するためにselfという引数が、重要になってくる。簡単に言うと倉庫みたいなものだ。selfには、どのインスタンス(部品セット)だったかを保存する機能がある。今回で言えばdog1というインスタンス(部品セット)が保存される。つまり、以下のような形となる。※数字の通り順番に読んでください。
class Dog: #②dog1というインスタンスが来た。まずは、__init__で初期化しよう。
def __init__(self, name): #③__init__初期化部署を使ってself(倉庫)に、dog1を保存する。
self.name = name #④dog1のnameには、与えてくれたname の値(ポチ)が入っているって各部署に伝える
def parts(self): #④partsという部署にself(dog1)の情報を与えよう。
print(f'my name is {self.name}') #⑤self(dog1)のnameの値(ポチ)を使おう
dog1 = Dog(name='ポチ') #①dog1というインスタンス(部品セット)には、name='ポチ'という部品が入っていて、それをDogというクラス(工場)に与えているよ
※別にselfという名前でなくても良い、testでもaでも何でも良いが、pythonの慣習的にselfが一般的となる
学んだこと
・クラスには__init__
とself
が必要。
・__init__には、インスタンスより与えられたデータを初期化する機能がある。
・selfには、インスタンスより与えられたデータを保存する機能がある。selfを使用して、ほかのメソッドに活用する機能が備わっていうる。
・クラスを活用する流れは、「クラスの定義 ➝ インスタンスの作成 ➝ メソッドの実行」。
・クラスの継承はまた今度。
初学者の参考になれば幸いです