• 一般社団法人Pythonエンジニア育成推進協会 顧問理事 寺田学氏

    著者:寺田学
    一般社団法人Pythonエンジニア育成推進協会 顧問理事

一般社団法人Pythonエンジニア育成推進協会(以下、当協会)の顧問理事の寺田学です。私は試験の問題策定とコミュニティ連携を行う立場です。 基本的に、プログラムを書くときにはオブジェクトを中心とした考え方が前提となりますが、Pythonの場合は学習し始めたばかりの段階でオブジェクト指向を知らなければ勉強ができないというものではなく、クラスやオブジェクトを意識しなくても使いこなすことができます。 とはいえ、もし今後、フレームワークを使用して何かを作りたいと考えているのであれば、クラスやオブジェクト指向について理解をしておいた方がスムーズに進むのは確かです。 そこで今回は、実践試験の範囲であり、主教材の4章にも掲載されている「クラス」や「オブジェクト指向」について2回に渡ってお話ししたいと思います。

Pythonはオブジェクト指向を知らなくても使いこなせるけど…

Pythonは、様々なプログラミングパラダイムをサポートしているため、オブジェクト指向によるプログラミングはもちろん、手続き型のように上から順番に処理をさせたり、処理をまとめて関数化させたりといったこともできます。 また、プログラミングパラダイムには関数型プログラミングという考え方があり、Python自体は純粋な関数型プログラミングで書くことはできませんが、それに近い関数型言語のように書くことはできます。 こういった様々な形で書くことができるPythonはオブジェクト指向にこだわる必要がない言語であると同時に、マルチパラダイムな言語であると言われています。 こういった特徴から、Pythonは学習を始める段階でオブジェクト指向やクラスを意識せずとも使いこなすことができますし、それらを知らなければ勉強ができないということはありません。 特にデータ分析の世界では、クラスによって独自のオブジェクトを意識してプログラミングをするといったケースは非常に少ないはずです。

一方で、Webやスクレイピングなどのフレームワークを使うケースでは、クラス構文を使い、オブジェクトを継承して様々なものを作るということはよくあります。そのため、フレームワークを使うのであればオブジェクト指向への理解は比較的求められることになり、見よう見まねでは限界を感じる場面に出くわすことがあると思います。

また、Pythonのint、str、dict、listなどの標準のデータ型はオブジェクト指向でできているため、その考え方に則ったメソッドが存在します。そのため、Pythonを完全に使いこなして、様々なものを理解するという意味では、オブジェクト指向を理解しておくと勉強になりますし、その先への発展にもつながりますので、ある程度学習が進んだ段階で理解を進めておくことをおすすめしています。

オブジェクト指向とはなにか

オブジェクト指向を厳密に説明するのは難しいので今回は深く言及しませんが、「クラスによって、独自のデータ型を開発する」ものであると考えてください。

まず、クラス構文を使うことで、実体となるものの大元の形を定義したオブジェクトの「ひな形」と呼ばれるものを作ることができます(これはデータ型とも呼ばれます)。 クラスにはデータを保持するためのもの(データ属性)とメソッドがあり、データ属性には保持するもののデータを入れたり、中間データを入れたりします。 一方のメソッドは、クラスの中にdef構文で書くことで振る舞いや操作をするといった、動作をしたりするものを言い、インスタンス化されたオブジェクトから呼び出すことができます。 そして、そのオブジェクトのひな形に基づいて「インスタンス化(実体化)」したものを「インスタンス」と呼びます。

つまり、足し算や引き算といった動作(メソッド)の準備をしているものがクラス構文によって作られた「ひな形」で、この「ひな形」を使って得た結果が「インスタンス」、ということになります。

オブジェクト指向を使った開発のメリットはコード量の削減と、管理の楽さ

オブジェクト指向のメリットは管理したいオブジェクトに対して最初から振る舞いを定義し、継承させられること、それによってコードの量を減らせるなど、後々の処理を楽にできるということにあります。

  • 各クラスはユーザークラスの特徴を引き継いでいながら、それぞれのクラスで必要な属性を追加・上書きすることができる

たとえば、上図のような「ユーザークラス」という「ひな形」を作成した場合、このひな形が持つ特徴を継承させた新たなクラスを用意することができます。上図の例で言えば先生クラス、生徒クラスがそれにあたります。 各クラスはユーザークラスの特徴を引き継いでいながら、それぞれのクラスで必要な属性を追加・上書きすることができます。

ユーザークラスがベースとなっているため、先生・生徒のクラスから氏・名・よみがな・性別・年齢といった基本的な項目を取得することが可能です。たとえばWebサイトのログイン後に氏名を表示させるメソッドを作成すれば、生徒クラスからも氏・名の項目を取得できます。また、よみがなの最初の文字を取得して何かの処理をさせるといったことも可能です。

先に挙げた例で言えば、四則演算という動作(メソッド)を最初からオブジェクトに持たせた状態で継承させられれば、そのためのスクリプトを毎回用意する必要はなくなります。 また、リストで利用できる<(リスト名).append>というメソッドがあります。これはクラス構文で定義された決まりに基づいた[1, 3]というリストがあったときに、<(リスト名).apend(5)>を実行することによって リストの中身を[1, 3, 5]に変更することができるというもので、これもまたあらかじめ振る舞いを定義されたメソッドのひとつです。

こういった、あらかじめ振る舞いが定義されたものが用意されているからこそ、様々な処理を簡易・容易に行うことができるようになります。 「ひな形」があって、「インスタンス化して使っている」と意識し、クラスにどういったものが実装されているかによって、インスタンス化された側の振る舞いや、データの持ち方が変わってくるということを覚えておきましょう。

インスタンス自身を示す第一引数、[self]は省略しないで

さて、クラスを書いていて、一番わかりにくいポイントはメソッドの第一引数として書かれる[self]です。 [self]はインスタンス自体を示すもので、Pythonでメソッドを定義する際には必ず第一引数に[self]を書きますが、呼び出す時には[self]が自動的に渡る仕組みになっています。 ここで、それならなぜメソッド定義時に書く必要があるのかと疑問に思うかもしれません。

前述の通り、メソッドは基本的に[def]で定義されますが、メソッドの中には[self]を引数に取らないものも存在します。 これは書籍でも解説していますが、クラスメソッドの第一引数にはクラスオブジェクトが来ますし、スタティックメソッドであれば[self]を取らないということです。

[self]を書かなくてもいいのではないかという議論は深くなりがちなところではあります。 実際、呼び出すときには自動的にインスタンスが[self]に渡るため、省略できるといえばそうであり、極論は「selfでなくてもなんでもいい」とも言えます。 しかし、後々のコードの読みやすさを考えれば、[self]と書いておいた方がいいと私は考えています。

本稿ではここまでにし、次回は特殊メソッドとデータ型の保証についてお話ししたいと思います。

当協会の最新情報は公式サイトか、公式Facebookページでご覧いただけます。FacebookページではPythonに関連したニュースもお知らせしていますので、ぜひフォローしてみてください。また、YouTubeチャンネル「Pythonエンジニア認定試験」では、私が試験概要や学習のコツをお話ししたものや、合格した方のコメント動画を公開しています。こちらもぜひご覧ください。

[PR]提供:Pythonエンジニア育成推進協会