オブジェクト指向って?
僕がPythonの学習を始めて、最初に難しいと感じた概念がオブジェクト指向(class)だ。
オブジェクト指向を一言で説明すると、値やメソッド(関数)を扱うためのコードをまとめて「オブジェクト(物)」として扱う考え方だ。
よく理解している人にとっては当たり前のことだが、使ったことがない初学者にとってはこれだけの説明ではイメージができず、曖昧な理解のまま他の学習に進んでしまう人が多い。
僕も最初は、参考書や動画で言っていることは理解できるけど、結局何が嬉しいの?、いつ使うの?、結局selfって何?と言ったような感覚だった。
僕と同じように上記のような感想を持っている人はご一読いただけたら幸いです。
オブジェクト指向のメリット
まず最初に簡単なオブジェクト指向を以下に示す。
詳細は、人間を表すオブジェクトで、自己紹介やn年後に何歳であるかを示すメソッドを用している。
# Class
class Human:
# コンストラクタ
def __init__(self, name, age, birth):
self.name = name
self.age = age
self.birth = birth
# 自己紹介メソッド
def introduce(self):
text = "私の名前は、{}です。今年で{}歳になります。"
print(text.format(self.name, self.age))
# 年齢加算メソッド
def future_age(self, n):
added_age = self.age + n
text = "私は{}年後、{}歳になります。"
print(text.format(n, added_age))
# インスタンス作成
sato = Human('佐藤', 20, '1999-10-03')
# 自己紹介メソッドを実行
introduce_text = sato.introduce()
# 年齢加算メソッドを実行 10年後の年齢を表示
future_age_text = sato.future_age(10)
# 私の名前は、佐藤です。今年で20歳になります。
# 私は10年後、30歳になります。
私がこれまでで感じたオブジェクト指向を習得するメリットをまとめると以下のような点がある。
- コード量の削減
- 変更の容易性
- 論文実装
- 独自アレンジ
それぞれのメリットについて順に説明する。
1. コード量の削減
classを作成することで圧倒的にコード量を減らすことができる。
Jupyter Notebookでコードを書いていて、付け加えたり、変更を加えることでコードがかなり冗長になったり、自分でも分かりにくくなったりした経験はないだろうか。
同じコードを何回も書いていたり、同じ関数を何度も実行したりしている場合、classを用いることで簡略できる。
例えば、上記のコードで説明すると、classを使わないと、人が変わるごとに、print文を何度も実行したり、age+nを何度も実行したりする必要がある。
そのような冗長性を削減し、コード量を減らすことで可読性が高いコードとなる
2. 変更の容易性
1.とも関連するが、コードを変更する際にもclassは大きな貢献をしてくれる。
同じコードを何度も書いていた場合、変更があった場合に多くの箇所を変更する必要が出てくる。
しかし、classを用いることで容易に変更ができるのだ。
例えば、誕生日を自己紹介で言いたくなった場合、上記のコードを以下のように変更するだけで良い。
# 自己紹介メソッド
def introduce(self):
text = "私の名前は、{}です。今年で{}歳になります。誕生日は{}です"
print(text.format(self.name, self.age, self.birth))
もしclassを使っていなかったら、自己紹介をした人全員のprint文に変更を加える必要がある。
3. 論文実装
ここからは少し上級者向けである。
僕個人としては、最新の論文等で発表される分析手法(特に深層学習)をGitHubから取得し、自身で実装する際にclassの知識は必要不可欠だと感じている。
というのも最新手法、特に深層学習手法などはほとんどの場合classで実装されている。
優秀なデータサイエンティストになるためには、scikit-learnの手法を用いるだけでは不十分で、最新の手法を使える力は必要不可欠だと考える。
最新手法を素早く理解し、キャッチアップするためにもclassは是非とも習得したい。
4. 独自アレンジ
classには継承という機能があり、すでに作成したclassに新たなメソッド等を簡単に追加できる。
# Humanクラスを継承したStudentクラスを作成
class Student(Human):
# コンストラクタ
def __init__(self, name, age, birth, student_id):
super().__init__(name, age, birth)
self.student_id = student_id
# 学生紹介メソッド
def introduce(self):
text = "私の名前は、{}です。今年で{}歳になります。学生番号は{}です。"
print(text.format(self.name, self.age, self.student_id))
このようにHumanクラスを継承し、学生番号も自己紹介で述べるStudentクラスなどを簡単に作成できる。
StudentクラスはHumanクラスのメソッドを引き継いでいるため、future_ageメソッドも用している。
オブジェクト指向が難しい3つのポイント
僕が学生にオブジェクト指向の指導をしていて感じる、オブジェクト指向の難しいポイントは以下3点だと考える。
- オブジェクトとインスタンスの違い
- オブジェクト指向を使う場面
- selfとは
こちらも順に説明していく。
1. オブジェクトとインスタンスの違い
学習を進めていく中で、オブジェクトとインスタンスという言葉が使い分けられているのが、違いが分からないという声をよく耳にする。双方クラスのことを指しているが、使う場面・用途が異なる。
Humanクラスで説明すると、オブジェクトは"Human"のことを指し、インスタンスは"sato"のことを指している。
インスタンス(instance)は英語で、「実例」という意味で、その意味の通りclassを用いて作成した具体的な物を指すのだ。
2. オブジェクト指向を使う場面
オブジェクト指向を使う場面としては、メリットの部分でも説明したが、冗長なコードを書いている時だ。
僕の場合を説明すると、
- Jupyter Notebookでipynbファイルにコードを書いてく。
↓ - コードが長いな、削って可読性を高めたい
↓ - 何度も利用する関数や処理を探す
↓ -
pyファイルにclassやdefを作成する
↓ - ipynbファイルでclassやdefをimportして、コード量削減
少しずつ長いコードを書くようになってくると、オブジェクト指向の偉大な力が発揮されるだろう。
3. selfとは
僕がオブジェクト指向を学習した時、一番理解に時間がかかったのがselfだ。
selfは自分自身を指していると考えてほしい。
例えば、インスタンス"sato"にとってのselfは"sato"自身を指していることになる。
self.をつける意味としては、2点ある。
- インスタンスを作成後、インスタンス内で用いた変数を呼び出すため
- あるメソッドで定義した変数を、他のメソッドで用いるため
前者に関しては、satoのnameを呼び出したい時、コンストラクタで、self.name = nameと定義することで、
print(sato.name)
# 佐藤
と呼び出すことができる。self.nameを定義していないと、このnameは出力できない。
後者に関しては、future_ageメソッドに注目していただきたい。
def future_age(self, n):
added_age = self.age + n
text = "私は{}年後、{}歳になります。"
print(text.format(n, added_age))
ここでself.age + nという処理をしているが、こちらもコンストラクタでself.age=ageと定義しているからこそ、他のメソッド(future_age)でも利用できるのだ。
この2点を理解するために、ぜひ手を動かしてみてほしい。selfをつけるつけないでどのような結果になるか試してみると、理解が深まるだろう。
おすすめ学習媒体
私がおすすめする学習媒体は2点ある。
1点目は、Udemyの講座でsaleの期間に買うと、お手頃な価格でオブジェクト指向をマスターできる。僕も購入した講座のURLを以下に示す。
2点目は、僕がX(Twitter)で運営している学習サポートを受講することだ。
プログラミングスクールに高くて通えない人向けに、データサイエンスの学習サポートを提供している。
オブジェクト指向の他にもデータ分析やGitHubの利用法など、包括的なデータサイエンスの学習サポートを各個人に対して行なっている。
少しでも興味を持った方は、お気軽にフォロー・DMしていただけると幸いです。