検索
連載

[Python入門]クラスの基礎知識Python入門(2/2 ページ)

クラスとオブジェクト、クラスの定義、インスタンス変数、__init__メソッド、インスタンスメソッドなど、クラスの基礎知識を紹介する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

__init__メソッド

 メソッドとは、あるクラス(やそのインスタンス)に固有の処理を実行するために使われる関数のことであり、クラス定義の中でdef文を使って関数を定義することで、それがメソッドとして扱われるようになる。__init__メソッドはそうしたメソッドの1つだが、Pythonでは特殊な扱いをされていて、インスタンスが生成される際に、そのインスタンスごとに固有の初期化処理を行うために、このメソッドが自動的に呼び出されるようになっているのだ(他の言語のコンストラクタに似たものといえる)。

__init__メソッド
__init__メソッド

 __init__メソッドの構文を以下に示す。

__init__メソッド

def __init__(self[, param]):
    インスタンスの初期化処理を行うコード


 selfが示すオブジェクトの初期化を行う。初期化の際に何らかのデータが必要であれば、パラメーターを介して、それらを受け渡せる。

パラメーター 説明
self 初期化処理を行うインスタンス
param 初期化に必要なデータを列挙する
__init__メソッドのパラメーター


 class定義の本体の中で、def文により関数を定義すると、それらはそのクラスのメソッドとなる。通常の関数とは異なり、その第1パラメーターは常に「self」となる。__init__メソッドの場合、パラメーターselfはその内部で初期化処理を行う対象となるインスタンスを示す。後で見る通常のメソッドは「インスタンス.メソッド(引数)」の形で呼び出すが(例:'str'.upper())、このときの「インスタンス」がselfに自動的に代入されるので、メソッド呼び出しでself自体を明示する必要はない点にも注意しよう。

 第2パラメーター以降にはインスタンスの初期化に必要となるものを列挙していく。例えば、ここではX座標の値とY座標の値が必要となる。__init__メソッドは自動的に呼び出されるので、どうやって__init__メソッドのパラメーターに値を渡すのかというと、クラスのインスタンス生成時に「クラス名()」形式の関数を呼び出してその引数に指定したものが、__init__メソッドに渡されるようになっている。よって、「point1 = Point(1.0, 1.0)」のようにすれば2つの浮動小数点数値が__init__メソッドに渡されるわけだ。これを受け取るには、__init__メソッドにも追加で2つのパラメーターが必要になる。

クラスのインスタンス生成と__init__メソッド呼び出し
クラスのインスタンス生成と__init__メソッド呼び出し

 そこで、Pointクラスのインスタンスを初期化する__init__メソッドを定義してみよう。

class Point:
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y

初期化メソッド__init__を追加したPointクラスの定義

 ここで注意したいのは、メソッド定義本体の「self.x」「self.y」という表現だ。これらは、「初期化対象のインスタンスの属性x」「初期化対象のインスタンスの属性y」を意味している、つまり先ほどのコードで行っていた以下の処理と同様な処理をクラス定義の中に含ませたといえる。これにより、インスタンスの属性xにパラメーターxの値が、属性yにパラメーターyの値が代入される。

point1.x = 1.0
point1.y = 1.0

クラス定義外で行われていた属性の初期化処理

 なお、上のコードではデフォルト引数値を指定しているので、「Point()」としてインスタンスを生成したときには、2つのパラメーターには「0.0」が渡される。

 上に示したクラス定義文を新たに実行することで、以前のPointクラスではなく、新しいPointクラスが作られる。そこで、これに合わせて2つのインスタンスpoint1とpoint2も作り直してみよう。

point1 = Point(1.0, 1.0)
point2 = Point()
print(f'point1: ({point1.x}, ({point1.y})')
print(f'point2: ({point2.x}, ({point2.y})')

2つのインスタンスを作成

 ここではpoint1インスタンスの生成では「Point(1.0, 1.0)」としているので、その属性(インスタンス変数)であるxとyは共に「1.0」で初期化される。一方、point2インスタンスの生成では引数を省略しているので、その属性(インスタンス変数)であるxとyは共に「0.0」で初期化される。

 では、point1が示す座標「(1.0, 1,0)」とpoint2が示す座標「(0.0, 0.0)」との距離も求めてみよう。これにはmathモジュールのsqrt関数を利用する(詳細は後述)。

from math import sqrt
print(sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2))

2点間の距離を求める

 実行結果を示す。

実行結果
実行結果

 あるクラスに属するオブジェクトが持つべきデータ(インスタンス変数)を明確にするには、__init__メソッドでそれらを初期化することが肝要だ。Pointクラスを例に取れば、そうすることで、そのインスタンスが必ず属性xとyを持つことが保証されるようになり、それら(の属性)を使った処理を安心して行えるようになる。

インスタンスメソッド

 最後に以下の2つの処理を行うメソッド(インスタンスメソッド)を定義しよう。

  • 原点からの距離を調べる
  • 他の座標との距離を調べる

 といっても、実はこれらは1つのメソッドにまとめられる。実際に計算を行うコードのひな型は既に上で見た通りだ。2つの座標「(x1, y1)」と「(x2, y2)」の距離は次の式で求められる。

2点間の距離を求める式
2点間の距離を求める式

 平方根を求めるにはmathモジュールのsqrt関数が使えるので、座標を表すPointクラスのインスタンスをpoint1とpoint2とすれば、「(point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2」を引数として、この関数に渡せばその距離が求められるというわけだ(「**」はべき乗演算子)。よって、インスタンスメソッドは次のように定義できる。

from math import sqrt

class Point:
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y
    def difference(self, point=None):
        if not point:
            point = Point()  # 原点を表すPointクラスのインスタンスを生成
        return sqrt((self.x - point.x) ** 2 + (self.y - point.y) ** 2)

2点間の距離を求めるdifferenceメソッドを追加したPointクラスの定義

 __init__メソッドと同様に、第1パラメーターはselfになる。「point1.difference(……)」のようにして、メソッドを呼び出したときには、selfにはpoint1オブジェクトが代入されることは覚えておこう。つまり、これはメソッド呼び出しに使われるPointクラスのインスタンスと、第2パラメーターに渡されたPointクラスのインスタンスとの距離を計算することになる。

 今述べたように、第2パラメーターにはPointクラスのインスタンスを渡すが、そのデフォルト引数値に「None」が指定されている。よって、differenceメソッド呼び出しで引数を指定しなかったときには、パラメーターpointの値はNoneになる。Noneは、値が存在しないことを意味する、Pythonの特殊な組み込み定数で、ブール演算を行う際には偽(False)として扱われる。

 そこで、まずはif文でパラメーターpointが偽かどうかを調べて、そうであれば原点(0.0, 0.0)を表すPointクラスのオブジェクトを作成することで、最終的には2点間の距離を求める公式を使って戻り値を計算するようにしている。こうすることで、原点からの距離と2点間の距離の両者を計算できるようにしている。もちろん、パラメーターpointが偽のときには、「sqrt(self.x ** 2 + self.y ** 2)」を計算して、そうでなければ2点間の距離を求めるようなコードにしても構わない。

 実際にPointクラスのインスタンスを幾つか作成して、この計算を行ってみよう。

point1 = Point(1.0, 1.0)
point2 = Point()
point3 = Point(5, 4)

print(point1.difference(point2))
print(point1.difference())
print(point3.difference(point1))

Pointクラスのインスタンスを幾つか生成し、それらの距離を計算する

 実行結果を以下に示す。

実行結果
実行結果

まとめ

 今回はクラスとオブジェクト、クラスの定義、インスタンス変数、__init__メソッド、インスタンスメソッドというクラスの基礎知識を紹介した。クラスが持つ属性には他にもいろいろとある。次回はそれらについて見ていくことにしよう。

今回のまとめ:クラス

  • クラスはインスタンスを生成するための設計図
  • Pythonのオブジェクトは全て何らかの型(クラス)に属している
  • プログラマーはclass文を使って独自のクラスを定義できる
  • クラスのインスタンスは「クラス名()」関数を呼び出すことで生成できる
  • クラスのインスタンスは、インスタンス変数やインスタンスメソッドなどの属性を持てる
  • __init__メソッドにより、インスタンス生成時に行う初期化処理を定義できる
  • インスタンスメソッドを定義することで、インスタンスが持つ属性を利用した処理を実行できる
  • メソッドの第1パラメーターには、その処理の対象となるインスタンスを表す「self」を置く

「Python入門」のインデックス

Python入門

Copyright© Digital Advantage Corp. All Rights Reserved.

前のページへ |       
[an error occurred while processing this directive]
ページトップに戻る