基本情報ではじめる Python (5) オブジェクト指向


2021-09-21 更新

この連載では、プログラミングの入門者を対象として、基本情報技術者試験の出題範囲にテーマを絞って、 Python の言語構文とプログラムの読み方を説明します。

今回のテーマは、 Python によるオブジェクト指向の基礎です。オブジェクト指向は、情報処理推進機構が公開している Python のサンプル問題でも取り上げられている重要なテーマなので、しっかりとマスターしてください。

オブジェクト指向とは?

オブジェクト指向は、プログラムの部品化に関する指向です。 Python では、プログラムの部品化に 2 つの指向が使えます。プロセス指向オブジェクト指向です。

プロセス指向では、関数を部品にします。
オブジェクト指向では、クラスを部品にします。

どちらの指向を使うのかは、プログラマの好みの問題ですが、一般的に言うと、小規模なプログラムには、プロセス指向が適していて、大規模なプログラムには、オブジェクト指向が適しています。

 

関数は、単独の機能を持った小さな部品です。関数は、外部から引数として渡されたデータを使って処理を行います。
クラスは、複数の機能を持った大きな部品です。クラスは、内部に保持しているデータを使って処理を行います。

たとえば、半径の値から、円周の長さと円の面積を求める部品を作るとしましょう。

プロセス指向
外部から引数として渡された半径の値から円周の長さを求める circle_perimeter 関数と、面積を求める circle_area 関数を、別々に作ることになります
オブジェクト指向
内部に半径の値を保持し、その値を使って円周の長さを求める perimeter メソッド と、円の面積を求める area メソッドを持つ、 Circle クラスを作ることになります
メソッド( method = 「やり方」)とは、クラスが持つ処理のこと

以下は、オブジェクト指向の図示技法としてよく使われる UML ( Unified Modeling Language )のクラス図を使って、 Circle クラスを示したものです。

info編集部注: スマートフォンでご覧の際は、プログラムや表は横スクロールすると全文をご覧になれます

Circle fast_forwardクラス名
radius fast_forwardクラスが内部に保持するデータ
perimeter()
area()
fast_forwardクラスが持つメソッド

クラス図では、四角形を 3 段階に区切り、上段にクラス名(ここでは Circle )、中段にクラスが内部に保持するデータ(ここでは radius )、下段にクラスが持つメソッド(ここでは perimeter() と area() )を記述します。メソッドは、メソッドあることがわかりやすいように、メソッド名の後に () を付けます。オブジェクト指向では、個々のメソッドではなく、クラス全体が 1 つの部品です。

クラスを定義する方法

先ほど UML のクラス図で示した Circle クラスを、 Python のプログラムで表してみましょう。

以下は、 Circle クラスを定義です。このプログラムを Circle.py というファイル名で作成しましょう。

infoお手元に Python の環境がない場合、ブラウザからオンラインで実行できる「 JupyterLab 」で、文中のコードをお試しください。 play_arrow ボタンを押すか「 Shift + Enter 」で実行できます

codePython で Circle クラスを定義したプログラム ( Circle.py )
# Circleクラスの定義
class Circle:
    # 初期化メソッドの定義
    def __init__(self, radius):
        self.radius = radius

    # 円周の長さを求めるメソッド
    def perimeter(self):
        return self.radius * 2 * 3.14

    # 円の面積を求めるメソッド
    def area(self):
        return self.radius * self.radius * 3.14

クラスは、

class クラス名:

という構文で定義します。

クラスのブロックの中に

def メソッド名(self, その他の引数, ・・・)

という構文で、メソッドを定義します。

メソッドを定義する構文は、関数を定義する構文と同様ですが、第 1 引数を self にする約束になっています。この self は「自分」という意味であり、そのクラスのインスタンス(インスタンスについてはあとで説明します)の識別情報が自動的に格納されます。それによって、メソッドの処理の中では、

self.変数名

という構文で、クラスのインスタンスが持つデータを読み書きできます。このデータをインスタンス変数と呼びます。

perimeter メソッドは、

self.radius * 2 * 3.14

という計算で得られる円周の長さを返します。

area メソッドは、

self.radius * self.radius * 3.14

という計算で得られる円の面積を返します。

self.radius は、「自分が保持しているインスタンス変数 radius 」という意味です。それでは、インスタンス変数 radius の実体は、どこにあるのでしょう?

それは、 __init__ メソッドの処理内容を見ればわかります。

特殊メソッド __init__ の役割

先ほど UML のクラス図で示した Circle クラスには、ありませんでしたが、 Python でクラスを定義するときには、 __init__ メソッドを記述します。 init は、 initialize (初期化)という意味です。

メソッド名の前後に、アンダースコア( _ )が 2 つずつあるのは、特定の場面で自動的に呼び出される特殊メソッドであることを意味しています。 __init__ メソッドは、クラスのインスタンスが生成された直後に、自動的に呼び出される特殊メソッドです。

__init__ メソッドの処理として、何を行うのかは、プログラムの目的次第ですが、多くの場合に、インスタンス変数を作成します。

self.radius = radius

の部分で、インスタンス変数 radius を作成し、それに radius という値を設定しています。

左辺も右辺も radius なので、混乱するかもしれませんが、 self が付いている self.radius がインスタンス変数であり、 self が付いていない radius は外部から引数として __init__ メソッドに渡された半径の値です。 Python は、変数を宣言せずに使う言語なので、この self.radius = radius によって、インスタンス変数 radius が作成されます。

インスタンスを生成して使う方法

クラスは、オブジェクトを定義したものです。クラスは、その機能が必要になった時点で、メモリにロードして使います。メモリにロードされたクラスが オブジェクト であり、クラスの インスタンス( instance = 「実例」)とも呼ばれます。

クラスを定義したプログラムは、ハードディスク上にあります。このプログラムをメモリにロードしたものが、クラスのインスタンスです。 1 つのクラスから、複数のインスタンスを生成することもできます。生成とは、メモリにロードすることです。

たとえば、以下の例は、 Circle クラスのインスタンスを 2 つ生成して、それぞれに c1 および c2 という名前を付けたときの、ハードディスクとメモリのイメージです。

図 Circle クラスのインスタンスを 2 つ生成した例

Python のプログラムで、 Circle クラスのインスタンスを生成して使ってみましょう。

以下は、 Circle クラスのインスタンスを 2 つ生成して、それぞれの機能を使うプログラムを、 Python の対話モードで実行したところです。説明の都合で、行末にコメントを付けていますが、実際に実行するときには、コメントは不要です。

infoお手元に Python の環境がない場合、ブラウザからオンラインで実行できる「 JupyterLab 」で、文中のコードをお試しください。 play_arrow ボタンを押すか「 Shift + Enter 」で実行できます

code図 Circle クラスのインスタンスを生成して使う(対話モード)
>>> from Circle import Circle	# Circleをインポートする
>>> c1 = Circle(10)		# 半径 10 のインスタンス c1 を生成する
>>> c2 = Circle(100)	# 半径 100 のインスタンス c2 を生成する
>>> c1.perimeter()		# c1の円周を求める
62.800000000000004
>>> c2.perimeter()		# c2の円周を求める
628.0
>>> c1.area()			# c1の面積を求める
314.0
>>> c2.area()			# c2の面積を求める
31400.0

クラスのインスタンスは、 インスタンス名 = クラス名(引数) という構文で生成します。

c1 = Circle(10)

によって Circle クラスのインスタンス c1 が生成され、引数 radius に 10 という値が渡されて __init__ メソッドが自動的に呼び出されます。

クラスの定義では、メソッドの第 1 引数に self がありますが、メソッドを呼び出すときには、 self を指定しません。 self は、自動的に付加されるようになっているからです。

同様に、

c2 = Circle(100)

によって Circle クラスのインスタンス c2 が生成され、引数 radius に 100 という値が渡されて __init__ メソッドが自動的に呼び出されます。

 

それぞれの半径の値を内部に保持したインスタンス c1 と c2 が生成されました。これ以降では、 インスタンス名.メソッド名() という構文で、メソッドを呼び出して使います。

c1.perimeter() c1.area() で、 c1 の円周と面積が求められます。
c2.perimeter() c2.area() で、 c2 の円周と面積が求められます。

perimeter メソッドと area メソッドを呼び出すときに、引数に半径の値を指定していないことに注目してください。これは、どちらのメソッドも、内部に保持している半径の値を使って処理を行っているからです。

いかがでしたか。 Python によるオブジェクト指向の基礎を、しっかりとマスターできたでしょう。

この連載では、今後も、基本情報技術者試験を Python で受けるための知識を取り上げて行きます。

それでは、またお会いしましょう!

 

label 関連タグ
Q. 午前試験を
『免除』するには?
A. 独習ゼミで午前免除制度を活用しましょう。
免除試験を受けた 87% の方が、
1 年間の午前免除資格を得ています。
2022 年 上期 試験向け
コース申込を開始!
最大 10 % OFF の早割も!
info_outline
2022 年 上期 試験向け
コース申込を開始!
最大 10 % OFF の早割も!
詳しく見てみるplay_circle_filled
label これまでの『基本情報ではじめるPython』の連載一覧 label 著者

『プログラムはなぜ動くのか』(日経BP)が大ベストセラー
IT技術を楽しく・分かりやすく教える“自称ソフトウェア芸人”

大手電気メーカーでPCの製造、ソフトハウスでプログラマを経験。独立後、現在はアプリケーションの開発と販売に従事。その傍ら、書籍・雑誌の執筆、またセミナー講師として活躍。軽快な口調で、知識0ベースのITエンジニアや一般書店フェアなどの一般的なPCユーザの講習ではダントツの評価。
お客様の満足を何よりも大切にし、わかりやすい、のせるのが上手い自称ソフトウェア芸人。

主な著作物

  • 「プログラムはなぜ動くのか」(日経BP)
  • 「コンピュータはなぜ動くのか」(日経BP)
  • 「出るとこだけ! 基本情報技術者」 (翔泳社)
  • 「ベテランが丁寧に教えてくれる ハードウェアの知識と実務」(翔泳社)
  • 「ifとelseの思考術」(ソフトバンククリエイティブ) など多数