プログラミング言語で重要な考え方であるオブジェクト指向をPython言語で実現するにはクラスやコンストラクタなどの機能を使います。プログラミングで頻出する考え方ですのでオブジェクトならではの考え方を知りPython言語でのクラスを用いたコードの書き方を知ってオブジェクト指向のコードが書けるようになりましょう。本記事ではPython言語でクラスを定義し拡張する具体的な書き方、クラスの使い方を解説します。
Contents
Pythonとは
Pythonはプログラミング言語の一つで、簡潔な文法と視覚的に見やすいコードの記法が特長で、他の言語に比べて誤解が少ない読みやすいコードを記述できます。90年代から世に出て、時代とともに改善が重ねられてきました。。
近年AI関連分野での利用例が多い言語ですが、AIだけでなく幅広い用途で使用できる言語です。タスクの自動化、数値計算、Webサイトのフロント開発など応用分野は広く利用者は多いです。大手IT企業や有名Webサービスでの利用例も多く、InstagramやYouTubeの初期版はPythonが開発に使用されていました。
オブジェクト指向との関係性
オブジェクト指向とはプログラミングの概念の一つで、プログラムを構成する部分部分をもの(オブジェクト)に例えてオブジェクトの組み合わせでプログラムを組み立てる考え方です。
Pythonはオブジェクト指向の機能を持ち合わせているため、オブジェクトやオブジェクトに付随する機能・情報を明確に記述し、プログラムのなかで使用できます。
関連記事:オブジェクト指向とは?原則やメリット・デメリットを徹底解説
クラス(class)とは
クラスとは、物としてのオブジェクトに備わっている共通の性質です。
オブジェクト指向では、オブジェクトを組み合わせてプログラミングしますが、オブジェクトのひな形になるのがクラスです。
以下、具体的に動物を例として説明いたします。
クラス
クラスの例として動物を取りあげます。
動物にはいろいろな生き物がいます。犬や猫など身近なものからライオンやコウノトリ、蛇や昆虫、カエルに至るまでいろいろです。生き物を必要に応じ似たもの同士でまとめ、クラスとします。
クラスは、いろいろな生き物の中から、共通の性質を持つ者をグループにして、共通の性質が何なのかを挙げて定義します。
オブジェクト
オブジェクト指向のプログラミング言語では、オブジェクトという用語をいろいろな場面で使うため文脈によってクラスやインスタンス(次項で説明します)の意味でオブジェクトという語が使われる場合があります。
オブジェクト指向を学習するときは、オブジェクトという用語が何を意味しているか、クラスなのかインスタンスなのか意識するようにしましょう。たいていの場合は特定のインスタンス群を指してオブジェクトと呼ぶことでしょう。
インスタンス
インスタンスは、クラスという共通の性質をもつグループに属する、個別の個体をプログラミングで使用する時の実体です。
具体例として、動物の例で説明します。
犬という共通の性質をもつクラスには、犬という同じ性質を持つ、具体的な一頭の犬たちがいます。ここでは インスタンスは、具体的に 隣の家のポチ、向かいの家のハスキー、我が家のシュナウザー、という個別具体的な情報を伴った存在としてプログラムのなかで働けます。
例えば、投げたボールをシュナウザーに探してもらったり、ボールを投げてハスキーにくわえてもらったりできます。 飼い主さんが「おすわり」とメッセージを送ればお行儀のよいシュナウザーはきちんとポーズを取ってくれるでしょう。賢いハスキーの目の前に二つの人形を置いたら二回吠え、三つの人形を置いた場合なら三回吠えるという動作を覚えてくれるかもしれません。
オブジェクト指向のプログラミングでは、シュナウザーというインスタンスに対し、ボールを探す・おすわり・人形はいくつ?などのメッセージを送ることでプログラムが働きます。
プログラムのなかで役割を持ったいろいろなクラスを決めておき、具体的な働き手としてハスキーやシュナウザーというインスタンスにメッセージを送ったり、場合によってはハスキーからシュナウザーにメッセージを送ることもあるかもしれません。 こうしてオブジェクト指向のプログラムは動作します。
クラスの再利用
クラスには階層を作って共通の性質をもたせられます。
例えば、動物クラスのなかでも陸上で活動する動物たちを四足歩行のグループで共通化でき、犬も猫も歩いたり、座ったりというメッセージに対応できるようにするなどの共通した性質を持たせることができます。もちろん、犬と猫では実際の骨や筋肉の構造は違うかもしれませんが、歩くという共通のメッセージに応えられればメッセージを発する側としては同じに見なすことができるわけです。
プログラミング言語によって共通の性質をもつオブジェクトを定義するやり方は異なりますが、Pythonでは継承を使います。
すべての動物は、呼吸する。四足歩行のグループは歩く、座る。四足歩行のグループは動物の性質を継承しているので呼吸もする、と性質を受け継いでいけるわけです。
クラス(class)の基本的な使い方
以下ではPythonで実際にクラスを定義し、使用する方法を見ていきましょう。変数やPythonの基本的な関数などにも簡単に触れます。
定義
Pythonでは、クラスの備える性質として代表的な物は、データ属性とメソッドです。 以下では、動物クラスAnimalを宣言し、 属性としてbreezeというメソッドを定義します。メソッドとはクラスに対するメッセージを処理する関数です。
class Animal:
def breeze(self):
print(“息を吸う”)
Pythonでクラスを定義するときはキーワードclassに続けてクラス名を指定します。そしてインデント内で属性を定義しています。メソッドには次項で触れます。
インスタンス化
前項で定義したクラスをプログラムで使用するにはインスタンスを作成します。あとで参照できるようにanimalという変数に代入してみます。
animal = Animal()
で変数animalはAnimalクラスのインスタンスが紐付きました。インスタンスを作成する操作をインスタンス化(instantiate)と呼びます。
前項でクラスの属性には、データ属性とメソッドがあると述べましたが、属性にはクラスに属する物とインスタンスに属する物を定義できます。以下、使用頻度の高いインスタンスに対する属性をご紹介します。
前項で動物クラスのメソッドbreezeを宣言しましたが、引数にselfを指定していました。メソッド宣言の最初の引数は自動的にインスタンスが代入された状態で実行されます。breezeの例では特に使用していませんがメソッド内でインスタンスを参照したいときにselfを使用できます。
メソッドは通常の関数を定義するときと同じくキーワードdefに続けてメソッド名と引数(ひきすう)を指定します。メソッドに持たせる引数がN個だとすると、引数は前出のselfを加えてN+1個で宣言します。定義したメソッドを呼び出す側はN個の引数をパラメータとして指定します。selfへインスタンスを渡すのはPythonインタプリタが自動でおこないます。
以下のようにインスタンス変数にドットで属性名を書くと、インスタンスのメソッドを呼べます。
animal.breeze()
コンストラクタ
次に動物の名前がわかるようnameというデータ属性をクラスに追加します。名前はAnimalのインスタンス化と同時に設定したいとしましょう。あとから名付けることもできますがなぜインスタンス作成時に設定するかというと、nameを持たないAnimalが生まれないようにするためです。
class Animal:
def breeze(self):
print(“息を吸う”)
def __init__(self, name):
self.name = name
特殊なメソッド __init__ を宣言していますが、__init__はコンストラクタと呼ばれるもので Pythonでは予約済みのメソッド名です。__init__の名で宣言されたメソッドは、インスタンス化にともなって自動で呼び出されます。メソッドには必須となるselfと動物の名前を指定するためのname引数を宣言しています。 コンストラクタ内ではインスタンスのデータ属性 self.name に引数で指定された名前を代入しています。
更新されたAnimalをインスタンス化するにはコンストラクタに渡すname引数が必要です。selfは指定せず名前のみを引数として指定し、下記のようにインスタンス化します。
frog = Animal(“カエル”)
で変数frogにはAnimalクラスのインスタンスが紐付きました。frogインスタンスのデータ属性nameにはインスタンス化と同時に文字列”カエル”が代入されます。
次に名前を表示するメソッドwhoを追加してみましょう。
class Animal:
def breeze(self):
print(“息を吸う”)
def __init__(self, name):
self.name = name
def who(self):
print(“私は” + self.name)
whoメソッドを追加したので、frog.who()を呼べば、
私はカエル
が出力されます。
デストラクタ
コンストラクタはクラスのインスタンス化にともない最初に呼び出されるメソッドでしたが、一方でプログラムのなかでインスタンスの利用が終わるときに特定の処理をおこないたい場合もあります。例えばインスタンスがファイルを読み書きしていたり外部のサーバーと通信していたりしてインスタンスの利用終了と同時にファイルを閉じたり通信を閉じる処理が求められることがあります。
こうした場合に、プログラマーが忘れずに始末用メソッドを呼ぶこともできますが、Pythonでは予約済みのメソッド名__del__でメソッドを宣言しているとインスタンスが利用されなくなった段階でPythonが自動で実行してくれるメソッドとなります。こうしたオブジェクトの始末用メソッドはデストラクタと呼ばれ、初期化を担うコンストラクタと対をなします。
Animalクラス内で__del__を宣言してみましょう。
class Animal:
def breeze(self):
print(“息を吸う”)
def __init__(self, name):
self.name = name
pass
def who(self):
print(“私は” + self.name)
def __del__(self):
print(“インスタンスが消えます”)
frog = Animal(“カエル”)
frog.who()
コードを実行すると、who以外のメソッドを呼んでいませんが、以下の出力が得られデストラクタ__del__が実行されたことがわかります。
私はカエル
インスタンスが消えます
継承
クラスをプログラムで使うとき、共通の性質をもつオブジェクトを定義するやり方として、Pythonでは継承を使用します。
Animalクラスの例では、Animalはwhoやbreezeというメソッドを持つ動物のクラスです。例えば、Animalと共通の属性を持つだけでなくさらに歩くことのできる四足歩行のグループとしてAnimalを継承したFourFootクラスを定義できます。
先ほどのAnimalクラスのコードに続けて、classを宣言します。Animalを継承するため丸括弧で囲ってAnimalを指定します。
# Animalのコードは前出と同じ。省略しています。
class FourFoot(Animal):
def walk(self):
print(self.name + “は、歩く”)
dog = FourFoot(“犬”)
dog.who()
dog.walk()
FourFootクラスのインスタンスdogはAnimalクラスから継承したwhoメソッドに加えてwalkというメソッドが使えることがわかります。
私は犬
犬は、歩く
のように、継承を使うと元のクラスのメソッドwhoやコンストラクタ__init__が使えるだけでなく追加のwalkメソッドを加えることで元のクラスと違う働きをさせられます。
また、継承するときは元のクラスのメソッドと同じ名前でメソッドを宣言でき、Pythonでは継承元のメソッドを上書きして置き換えます。同じメソッドで違う働きをさせられます。
class FourFoot(Animal):
def walk(self):
print(self.name + “は、歩く”)
def __del__(self):
print(“歩き終わった”)
dog = FourFoot(“犬”)
dog.who()
dog.walk()
FourFootクラスでデストラクタ__del__を定義しAnimalクラスとは違う出力をさせてみます。出力は
私は犬
犬は、歩く
歩き終わった
となり処理の終わりに異なるメッセージが出力されデストラクタが実行されたことがわかります。
classを使用する際の注意点
今まで__init__やwhoなどのメソッドとself.nameなどのデータ属性を例に見てきました。
self.nameやwhoはインスタンスに属していて特に区別する場合はインスタンスのデータ属性、インスタンスのメソッドなどと呼びます。インスタンスの属性とは別にクラスに属するデータ属性やクラスのメソッドもPythonでは定義できます。詳しくは触れませんがそうした区別があることを知っておきましょう。
また、クラスを継承してさらに継承して、と階層を深くしていくことができますが無闇に継承して似たようなクラスが増えてしまうと使用時に混乱の元となります。定義しているときは便利に思うかもしれませんがクラスを使用する側からすると使いづらいものとなってしまうため注意が必要です。
クラス名には先ほどのFourFootクラスのように大文字で単語をつなげるのがPythonの慣習です。メソッド名や変数名などは小文字でmy_lovely_schnauzerのようにアンダースコアで単語をつなげるのがお決まりとなっているのでクラスを宣言する際に複数の単語をつなげるときはアンダースコアを入れずに大文字で単語を始めることを忘れずに。
Pythonエンジニアの年収・報酬単価相場
弊社TechReachでPythonを使用する案件を検索すると、すべての案件の三分の一に相当する144件(2023年1月TechReach調べ)で月単価が80万円を超えています。
年収換算で960万円超となる案件ではPythonの利用が増えているAI・機械学習のスキルや、データ分析やテストのスキル、成長企業での迅速な機能改善サイクルをおこなっていく力などコーディングだけでなく高度な分析力やマネジメント力、コミュニケーション能力が求められることが多くあります。
PythonはAIなど先進分野で使われることから今まさに伸びているサービス提供企業で使われることが多く、応用範囲が多岐にわたるためサービスの提供分野毎に求められるスキルは異なってきます。まずはコアとなるPythonのコーディング能力を高め、AIなどの具体的な応用分野のスキルを身につけていく必要があります。
まとめ
Pythonでのクラスの定義とインスタンスのデータ属性やメソッド、コンストラクタを見てきました。
継承によって似た性質を持つオブジェクトを定義し理解しやすく無駄のないプログラムを作成できるクラスの機能をものにして大規模なコーディングに対応できるスキルを身につけていきましょう。
クラスの概念は他のプログラム言語でも使われることが多いです。Pythonでクラスを学び、他のオブジェクト指向プログラミング言語での考え方の参考にしてください。
フリーランスの案件をお探しの方はTechReachにご相談ください。
TechReachを運営する株式会社アールストーンはIT・Web業界特化で15年以上の実績がございます。
そのため、高単価・高品質な数多くの案件紹介が可能です。
また一人のコンサルタントが企業と求職者様の担当を行う「両面型エージェント」を採用しているため、あなたの希望に合う案件がきっと見つかるはずです。
TechReachを活用して、理想の案件を見つけましょう!