Pythonのオブジェクト指向を理解する②~クラスとインスタンスの違いを分かりやすく解説する

この記事は約10分で読めます。

 

今回はPythonにおけるクラスとインスタンスについて解説していきたいと思います。このクラスを理解するためには、オブジェクト指向とは何かについても知る必要があります。

 

 

オブジェクト指向とは何か?

 

 

 

まずオブジェクト指向とは何かをざっくりいうと、「処理内容ごとにプログラムをファイルに分けてパーツ化すること」を指します。

 

なぜ処理内容ごとに細かくファイルに分ける必要があるのかというと、数十行で書けるような簡単なプログラムの場合だと別に気になりませんが、実務で数万行~になる大きなシステムを作るとなった場合、それを全て1つにファイルにまとめると、プログラムのメンテナンスする場合、どこのコードがプログラムのその部分なのか把握するのが非常に面倒です。

 

そのため何人ものエンジニアが開発に携わるような大きなシステム(プログラムを作る場合)はプログラムの作業内容ごとに、ファイルを分けて記述することが推奨されています。これを「オブジェクト指向」です。

 

プログラミングもガンプラを作るのと同じ要領で、組み立てやすくするように手の部品、足の部品と部分ごとに目印をつけてあげる、そんなイメージです。

 

イマイチピンとこない人のために例を上げるならば、もしブログの記事をランダムでTwitterに投稿するプログラムを作る場合、その処理内容は「ブログにアクセスして記事の内容を取得する」、「twitterにアクセスしてその内容をツイートする」という2つに分かれるので、プログラムのメンテナンスがしやすいようにそれぞれの処理を別のファイルにまとめて実行ファイル上からそれらのファイルを逐一呼び出すという流れになります。

 

こういった様々な処理を組み合わせたプログラムを作る場合は処理内容ごとに別々のファイルに分けて書いて、状況に応じて呼び出す仕組みにしておくことで、後からコードを見た人がメンテナンスしやすいようにしようというコードの書き方が「オブジェクト指向」なのです。

 

 

モジュールとライブラリ

 

そして、Pythonにおいて、実行ファイル上に呼び出せる別のファイルに書いてあるプログラムのことを『モジュール』または『ライブラリ』と言います。

 

Pythonを勉強するとモジュールとライブラリの違いって何なの?と思うことがありますが、Pythonにおけるライブラリというのは別の場所から関数を呼び出す(API的な?)処理全般を指しているので、モジュール=ライブラリという認識でいいかなと思います。

 

例えばPython使う上で絶対書くであろう「import 〇〇」という処理はPCの別の場所に保存されている〇〇.pyに書かれたクラス・関数を呼び出しています。

 

 

クラスと関数って何のためにあるの?

 

このモジュール上によく書かれるクラスと関数ですが、なぜわざわざclass:だったりdef:だったりで一々処理を纏めるのかというと話ですが、まず関数を使う理由は大きく2つあります。

 

まず1つ目は「同じ処理を関数化することでコードを短くして見やすくする」というものがあります。そして2つ目は「細かい処理を関数という形で分けることでよりコードのメンテナンスをしやすくする」という理由からです。

 

例えば先ほどのTwitterに投稿するという処理ならTwitterにアクセスする・メアドとパスワードを入力してログインする・ツイートする・ブラウザを閉じるという4つの処理に分かれますのでそれぞれの処理ごとに関数を定義したりします。

 

そして、クラスとは何なのかというと一言でうまく言うのは難しいのですが、個人的な認識としては、モジュール(ライブラリ)がその処理に関する大まとめとした場合、クラスはその処理に関係する関数・基本データを含んでいる小まとめというイメージです。

 

そして、プログラミングではこのクラスを元にして、便利な性質を新しくオブジェクト(インスタンス)を生成することが出来ます。身近な例でいうならば、「Pandas」「Numpy」のPandas.dataframeやNumpy.arrayなんかは新しく作った便利なクラスの代表例ですね。

 

他にもゲームなんかを作る場合は、オークやエルフなど特定の種類のキャラクターの体力などの基本情報なんかをクラスにしてまとめることもあります。

 

 

スポンサーリンク
スポンサーリンク

クラスとはオブジェクトの仕様書である

 

私たちがプログラミングにおいて変数(オブジェクト)を作る場合、基本的にそのオブジェクトがどういう性質なのか定義しなくてはいけません。

 

変数(オブジェクト)はstr intなどのクラスの中から作られます。すなわち、クラスは「どんな性質を持ったオブジェクトを作るか?」を書いたオブジェクトの仕様書、設計図だと言えます。

 

オブジェクトにどんな機能があるかは、そのオブジェクトの仕様が定義してあるクラスを知ればわかります。Pythonの場合ならばprint(type() )で確認できます。

 

オブジェクトを作るのに参照したクラスは「型」と呼ばれますが、一応オブジェクトの型はクラス以外でも定義できます(構造体で定義できる)。C言語なんかだと、型はオブジェクトの機能だけではなく、必要となるメモリサイズなども表します。

 

まあPythonの場合は向こうが定義したデータから勝手にクラスを推測して定義してくれる「動的型付け言語」に分類されるので、型のことが特に分からなくとも簡単に変数を作成できてしまいます。

 

例えばPythonだと

 

#変数を定義する
a='HELLO'

 

というオブジェクトを定義して、print(class(A))を実行するとstrと返されます。

 

#変数:オブジェクト(この場合だとa)のクラスを確認する
print(type(a))


※<class 'str'>

 

これはhelloという文字列を格納している「a」というオブジェクトのクラスが、strクラス(文字型)であることを示しています。

 

本来Cやデータベースとかだと自分でstringと書いて、今から新しく作る変数は文字型だよ~と定義してあげなければいけませんが、Pythonの場合は基本的に向こうが勝手に型推測してクラスを付けてくれるので、こっちがわざわざ宣言する必要がありません。

 

プログラミングで初心者がエラーを連発して詰まる原因の大半は変数の型についてのあれこれなので、そこをあまり気にしなくていいというのが初心者にとって優しい点ともいえるわけですが、同時に型についての意識が薄くなってしまいます。

 

最初のうちは型を意識しない方がサクサク進めるので良いことと言えばいいことなのだと思いますが、適当に変数を宣言しても勝手に型付けしてくれると型に対する意識が低くなってしまうというデメリットもあります。

 

型を意識しないと自分以外の大勢と一緒にプログラムを開発する大規模開発においてはネックになることもあるので、型を指定しなくていい動的言語についてはメリット・デメリットどちらともある印象です。

 

まあ型・クラスが分からなくてプログラミングそのものを挫折するくらいなら、型付けの理解を深めなくても次に進めるPythonはやはり初心者向け言語として一番いいかなと思います。

 

 

『クラス』と『インスタンス(オブジェクト)』の違い

 

そして、これも初心者の人から良く聞かれる質問ですが、クラスとインスタンスの違いについてもざっと触れておくと、Pythonにおけるインスタンスとは、クラスをもとにして定義されたオブジェクトのことを指します。そういう意味では「クラス≒インスタンス」という認識で大丈夫だと思います。

 

具体例として皆さんがよく使う外部から呼び出ているであろうインスタンスの例を挙げると、Pandas.Dataframeやnumpy.arrayなんかが代表的だと思います。

 

これらは最初に「import Pandas」「 import numpy」という風に宣言してライブラリからPandas.dataframe・numpy.arrayクラスを呼び出すことで使えるようになるインスタンスです。

 

PandasやNumpyのクラスの性質をもった変数(オブジェクト)を定義する際のpandas.dataframe()なんかの関数をインスタンスと言います。そしてクラスは外部から呼び出すものだけではなく、デフォルトでPythonに備わっているクラスもたくさんあります。

 

例えばPythonのプログラミング入門書で最初に出てくる数値、文字列、リスト、タプル、辞書型などは、すべてデフォルトでPythonに備え付けられているれっきとしたクラスです。基本的にPythonでは定義されるオブジェクトは全て何かしらのインスタンスをもとに作成されています。

 

なので、intやstrもインスタンスと言えばインスタンスですが、これらの型(クラス)は動的型付け言語では、わざわざ自分でクラス(型)を定義する場面があまりないので、そこまで意識する場面はありません。リストなんかはlist()で生成したオブジェクトが「インスタンス」だと言えます。これを↓のコードで解説します。

 

 

# 変数に代入できるものは一応インスタンスオブジェクト

a = 1
※int(数値)


b = 'Helloworld!'
※str(文字)


c = [1,2,3,4]
※list(リスト)

 

 

インスタンスの存在を意識するのは、やはりPandasやNumpyでnumpy.array()Pandas.dataframe()を使って変数を定義する時ですね。こういったインスタンスを使用して作られた関数はpandasやNumpyの性質を持っているので、変化率や移動平均が関数1つで簡単に計算出来たり、行列のように扱うことができるので便利です。このインスタンスで使える便利な関数のことを『メソッド』と言います。

 

Pandasなら移動平均を計算できる「変数名.rollong()」なんかがPandasというクラスに備わっていて、その性質を持つオブジェクトで使用できるメソッドだと言えます。

 

よく使われるクラスとインスタンスの例としては、たい焼きの型とたい焼きの例えななんかがあります。タイ焼きの型の設計図が『クラス』で。『インスタンス』とは、その設計図を元にして量産したタイ焼きの型であり、このインスタンスにデータという汁を流し込んで出来上がるのが、オブジェクト(変数)という訳です。

 

なので、出来上がるたいやきの形は同じだけれども、流し込む汁がチョコレートであればチョコ味になるし、カスタードであればカスタード味というオブジェクトとしては別のものになります。

 

クラスとしての大まかな性質は同じだけども、型に入れるデータによって1つ1つ細かいところはオブジェクト(インスタンス)によって異なるという感じです。

 

 

まとめ

 

オブジェクト指向プログラミングにおけるクラスとは、オブジェクトを生成するための設計図あるいはひな形に相当するもので抽象データ型の一つです。 クラス定義を行うことで、そのクラスの性質を持ったオブジェクトを作ることができるようになります。Pythonの場合はPandasやnumpyなど外部のライブラリに便利な機能を搭載したクラスが用意されています。

 

ここまでクラスとインスタンスについてざっと解説してきましたが、言葉だけではイマイチ実感がわかないと思うのでここからは実際にPython上でクラスと関数を作ってみたいと思います。

 

 

 

コメント

タイトルとURLをコピーしました