Python

【Python】クラスの定義方法と使い方を解説

この記事では、Pythonのclass(クラス)について解説します。

クラスとは、つまりは「」のことです。クラスを定義することでint型やstr型と同じような便利な型を自ら作ることができます。

ちなみに、元から言語が用意してくれている型を「組み込み型」と呼び、ユーザーが定義した型のことを「ユーザー定義型」と呼びます。そのまんまですね!

型ってなんだっけ?

データの性質を定めて取り扱い方を定義したもの

それでは、クラスの使い方を見ていきましょう!

クラスの使い方

クラスの使い方をステップごとに見ていきます。

  • STEP1
    クラスを定義する

    クラスは、classキーワードを使って以下のように定義します。

    class クラス名:
        # 何かしらの処理

    クラス名の頭文字には大文字を使いましょう。また、複数の単語がくっついた名前を使用する場合は、単語の頭文字を大文字にします。例えば「MyClass」みたいな感じです。

    クラスの中には「コンストラクタ」や「メソッド」を定義しますが、詳しくは後述します。

  • STEP2
    インスタンス化

    クラスを使うには、そのクラスのインスタンスを生成する必要があります。

    インスタンスとは?

    クラスを元に生成したデータのこと

    インスタンスを生成するには、以下のようにクラスを呼び出します。

    インスタンス名 = クラス名()

    このようにクラスのインスタンスを生成することをインスタンス化と呼びます。1つのクラスからインスタンスはいくつでも生成することができます。

  • STEP3
    クラスの機能を呼び出す

    インスタンス化したことにより「インスタンス変数(クラスに定義されている変数)」「メソッド(クラスに定義されている関数)」を呼び出すことができます。

    呼び出す際は.(ドット)で繋いで呼び出します。

    インスタンス名.変数名
    
    インスタンス名.メソッド名()

    インスタンス変数とメソッドについては後述します。

という感じの流れでクラスは使用されます。

インスタンスについて

クラスとインスタンスのたとえ話として、たい焼きの話をよく目にします。

たい焼きを焼く鉄板がクラスで、たい焼きがインスタンスとして表されます。これは、鉄板(クラス)さえ作ってしまえば、たい焼き(インスタンス)はいくらでも生成できるということです。そして、たい焼き(インスタンス)の中身は、たい焼きによって変更することができます。

このたとえ話をコードとして表すと以下のようになります。

# たい焼きクラス
class たい焼き:
    def __init__(self, 中身):
        self.中身 = 中身

# インスタンス生成
あんこたい焼き = たい焼き('あんこ')
カスタードたい焼き = たい焼き('カスタード')

print(あんこたい焼き.中身)
# あんこ

print(カスタードたい焼き.中身)
# カスタード

※ 今回はわかりやすさを重視して、クラス名や変数名を日本語で記述しました

上記のコードは、たい焼きクラスから「あんこたい焼きインスタンス」と「カスタードたい焼きインスタンス」を生成し、中身を出力しています。このように、一度クラスを作ってしまえば何度でもインスタンスを生成することができます。

コンストラクタ(イニシャライザ)

コンストラクタは、クラスをインスタンス化する際に呼び出されます。インスタンスを初期化する際の処理を定義できます。

定義

コンストラクタは__init__という特殊メソッドを使って定義します。

class クラス名:
    # コンストラクタ
    def __init__(self):
        # なんらかの処理

以下のように引数を受け取ることもできます。

class クラス名:
    # コンストラクタ
    def __init__(self, 引数1, 引数2, ..., 引数N):
        # なんらかの処理

呼び出し

引数が定義されている場合は、インスタンス化する際に値を渡す必要があります。

# コンストラクタに引数が定義されていない場合
インスタンス名 = クラス名()

# コンストラクタに引数が定義されている場合はその分だけ値を渡す
インスタンス名 = クラス名(値1, 値2, ..., 値N)

サンプル

試しにコンストラクタを定義し、インスタンス化してみましょう!

class TestClass:
    # コンストラクタ
    def __init__(self):
        print('TestClassのコンストラクタが呼び出されました!')


# TestClassのインスタンス化
tc = TestClass()

実行結果

TestClassのコンストラクタが呼び出されました!

ちなみにコンストラクタは「イニシャライザ」とも呼ばれ、特に何も定義しないならば省略することもできます。

デストラクタ

デストラクタは、インスタンスが削除される際に呼び出されます。

定義

デストラクタは__del__という特殊メソッドを使って定義します。

class クラス名:
    # デストラクタ
    def __del__(self):
        #何かしらの処理

サンプル

試しにデストラクタを定義して使ってみましょう!

class Test:
    # デストラクタ
    def __del__(self):
        print('デストラクタが呼び出されました!')


t = Test()

print('-'*30)
# del文でインスタンスを削除
del t
print('-'*30)

実行結果

------------------------------
デストラクタが呼び出されました!
------------------------------

このサンプルではdel文を使って明示的にインスタンスを削除しましたが、プログラム終了時にはインスタンスも削除されるのでデストラクタが呼び出されます。

selfとは?

コンストラクタやデストラクタに定義されているselfという引数が気になったかと思います。

selfとは、自分自身(インスタンス)にアクセスするためのものです。クラスに定義されたコンストラクタやデストラクタを含めたメソッドは基本的にselfを引数に持ちます。

以下のコードではselfで取得したオブジェクトとインスタンスを出力しています。

class Test:

    def __init__(self):
        # selfの出力
        print(self)


test = Test()
# インスタンスの出力
print(test)

実行結果

<__main__.Test object at 0x1039994d0>
<__main__.Test object at 0x1039994d0>

selfとtestインスタンスはまったく同じ値が出力がされたので、selfはインスタンスにアクセスしていることが確認できました!

インスタンスにアクセスすることでクラス内で自身の機能(インスタンス変数やメソッド)を使うことができます。

selfの使い方については都度で解説するので、ここでは「selfは自身のインスタンスにアクセスしてるんだ〜」という認識で構いません。

クラスに定義できる変数

クラスには、2種類の変数を定義することができます。

インスタンス変数

インスタンス変数は、インスタンス化しなければ呼び出せない変数です。

定義

インスタンス変数を定義するには、コンストラクタ内でselfを用いて定義します。

class クラス名:
    def __init__(self):
        self.インスタンス変数名 = 初期値

もちろん、引数の値を渡すこともできます。

class クラス名:
    def __init__(self, 引数):
        self.インスタンス変数名 = 引数

呼び出し

インスタンス変数を呼び出すに以下のようにします。

インスタンス名.インスタンス変数名

サンプル

試しにいくつかインスタンス変数を定義して出力してみましょう。

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


zero = Person('綾波レイ', 14, '女')
print(f'名前: {zero.name}, 年齢: {zero.age}, 性別: {zero.gender}')

first = Person('碇シンジ', 14, '男')
print(f'名前: {first.name}, 年齢: {first.age}, 性別: {first.gender}')

実行結果

名前: 綾波レイ, 年齢: 14, 性別: 女
名前: 碇シンジ, 年齢: 14, 性別: 男

動的な定義

インスタンス変数は、インスタンスを生成した後からでも追加できます。

class Person:
    def __init__(self, name):
        self.name = name


p = Person('ムスカ')
# 動的にインスタンス変数を追加
p.age = 28

print(p.name)
print(p.age)

実行結果

ムスカ
28

Pythonでは、このように後から簡単にインスタンス変数を追加できます。

クラス変数

クラス変数は、インスタンス化しなくても呼び出すことができる変数です。

定義

クラス変数を定義するには、クラス内で変数を定義します。

class クラス名:
    # クラス変数定義
    クラス変数名 = 値

呼び出し

クラス変数を呼び出すには、以下のように呼び出します。

クラス名.クラス変数名

サンプル

試しにクラス変数を定義して呼び出してみましょう!

class Test:
    # クラス変数の定義
    var = 'クラス変数'


# クラス変数の呼び出し
print(Test.var)

実行結果

クラス変数
クラス変数はインスタンスからでも呼び出せますが、紛らわしいのでクラスから呼び出すようにしましょう!

同名の変数が定義されている場合

同名のクラス変数とインスタンス変数が定義されている場合、インスタンスからはインスタンス変数が呼び出されます。

class Test:
    var = 'クラス変数'

    def __init__(self):
        self.var = 'インスタンス変数'


t = Test()
print(t.var)
# インスタンス変数

実行結果

インスタンス変数

クラス内に定義した関数(メソッド)

クラス内に定義した関数のことを「メソッド」と呼びます。メソッドには、3つの種類があります。

インスタンスメソッド

インスタンスメソッドは、インスタンス化しないと呼び出せないメソッドです。

定義方法

インスタンスメソッドは、以下のように定義します。必ず引数にselfを記述する必要があります。

class クラス名:

    # 引数無し
    def メソッド名(self):
        # 何らかの処理

    # 引数有り
    def メソッド名(self, 引数1, 引数2, ..., 引数N):
        # 何らかの処理

呼び出し方法

インスタンスメソッドを呼び出すには、以下のようにします。

# 引数無し
インスタンス名.インスタンスメソッド名()

# 引数有り
インスタンス名.インスタンスメソッド名(値1, 値2, ..., 値N)

サンプル

試しにインスタンスメソッドを定義して使ってみましょう!

class Cat:

    # インスタンスメソッド
    def cry(self):
        print('にゃ〜')


tama = Cat()
tama.cry()

実行結果

にゃ〜

selfを使ってインスタンスにアクセスする

selfを使ってインスタンスにアクセスすることで、自身のインスタンス変数やインスタンスメソッドを呼び出すことができます。

class Animal:

    def __init__(self, name, sound):
        # インスタンス変数
        self.name = name    # 名前
        self.sound = sound  # 鳴き声

    def cry(self):
        # インスタンス変数の呼び出し
        print(self.sound)

    def output(self):
        # インスタンス変数の呼び出し
        print(self.name)
        # インスタンスメソッドの呼び出し
        self.cry()



cat = Animal('たま', 'にゃ〜')
cat.output()

実行結果

たま
にゃ〜

このように、selfを使うことで自身のインスタンス変数やメソッドを呼び出すことができます。

クラスメソッド

クラスメソッドは、インスタンス化しなくても呼び出せるメソッドです。
selfを使ったインスタンスへのアクセスはできません。

定義

クラスメソッドは、以下のように@classmethodデコレータを使って定義します。
引数にはclsを必ず定義する必要があります。

class クラス名:

    # 引数無し
    @classmethod
    def クラスメソッド名(cls):
        # 何らかの処理

    # 引数有り
    @classmethod
    def クラスメソッド名(cls, 引数名1, 引数名2, ..., 引数名N):
        # 何らかの処理

呼び出し

クラスメソッドを呼び出すには、以下のようにします。

# 引数無し
クラス名.クラスメソッド名()

# 引数有り
クラス名.クラスメソッド名(値1, 値2, ..., 値N)

サンプル

clsにアクセスすることで、自らのクラスを呼び出すことができます。

class Point:
    # クラス変数
    num = 10

    def __init__(self, x, y):
        self.x = x
        self.y = y

    # クラスメソッド
    @classmethod
    def class_method(cls):
        # Point(1, Point.num)と同等
        return cls(1, cls.num)

    # 出力
    def output(self):
        print(f'x: {self.x}, y: {self.y}')


# クラスメソッドの呼び出し
p = Point.class_method()
p.output()
print(type(p))

実行結果

x: 1, y: 10
<class '__main__.Point'>

スタティックメソッド

スタティックメソッドは、インスタンス化しなくても呼び出せるメソッドです。
self、clsにはアクセスすることができません。

定義方法

スタティックメソッドは、以下のように@staticmethodデコレータを使って定義します。引数にselfやclsは使えません。

class クラス名:

    # 引数無し
    @staticmethod
    def メソッド名():
        # 何らかの処理

    # 引数有り
    @staticmethod
    def メソッド名(引数名1, 引数名2, ..., 引数名N):
        # 何らかの処理

呼び出し方法

スタティックメソッドを呼び出すには、以下のようにします。

# 引数無し
クラス名.スタティックメソッド名()

# 引数有り
クラス名.スタティックメソッド名(値1, 値2, ..., 値N)

サンプル

試しにスタティックメソッドを定義して使ってみましょう!
通常の関数をクラス内に定義できるイメージです。

class Test:

    @staticmethod
    def s_method():
        print('スタティックメソッドです!')


# スタティックメソッドの呼び出し
Test.s_method()

実行結果

スタティックメソッドです!

属性(attribute)

属性とは、「a.b」の「b」のことを言います。「.」で繋げて呼び出されるものは全て属性です。具体的に言えば、インスタンス変数やメソッドなどは属性です。

dir()を使うことで、オブジェクトが持つ属性を確認することができます。

class Test:
    # クラス変数
    hoge = 'hoge'

    def __init__(self):
         # インスタンス変数
         self.moge = 'moge'

    # インスタンスメソッド
    def method(self):
         print(self.moge)


# クラスの属性の確認
print(dir(Test))

# インスタンスの属性の確認
t = Test()
print(dir(t))

実行結果

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hoge', 'method']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hoge', 'method', 'moge']

大量にある'__メソッド名__'は、特殊メソッドと呼ばれるメソッドです。コンストラクタやデストラクタもこれに含まれます。

実行結果を右にスクロールして最後の方を見て下さい。
どちらの出力結果にもTestクラスの属性が追加されているのがわかります。

mogeはインスタンス変数なので、インスタンス化しないと生成されません。

継承

クラスは継承することができます。

継承とは「あるクラスから派生したクラスを定義すること」を言います。継承させることで親の性質や機能を引き継ぎ、さらに拡張・追加することができます。

例えば、文字列を扱いたいけど通常のstr型では物足りないなっと思った時に、str型を継承した新しいクラスを定義し、自分が欲しい機能を追加できます。

# クラス名の後ろに(継承する型名)を記述する
class MyStr(str):

    def 追加するメソッド(self):
        print('追加メソッド')


ms =  MyStr('ABC')
ms.追加するメソッド()

# もちろん、strのメソッドも使用可能
ms.index('B')

実行結果

追加メソッド

str型に定義されているメソッドを拡張・変更することも可能です。

【Python】継承の使い方【派生クラスの定義】この記事では、Pythonの継承の使い方について解説します。継承を使うことでクラスの性質を引継ぎ、拡張・変更した新しいクラスを定義することができます。もちろん組み込み型のクラスを継承することもできます。それでは、Pythonの継承の使い方を見ていきましょう!...

まとめ

この記事では、Pythonのクラスについて解説しました。

今回のおさらい

わからない箇所があったら記事を読み返してみましょう!

クラスの定義

class クラス名:

    # クラス変数
    クラス変数名 = 値
    
    # コンストラクタ
    def __init__(self, 引数名):
        # インスタンス変数
        self.インスタンス変数名 = 引数名

    # デストラクタ
    def __del__(self):
        なんらかの処理

    # メソッド
    def メソッド名(self):
        なんらかの処理

    # クラスメソッド
    @classmethod
    def クラスメソッド名(cls):
        なんらかの処理

    # スタティックメソッド
    @staticmethod
    def スタティックメソッド名():
        なんらかの処理

インスタンス化

# インスタンス化
インスタンス名 = クラス名()

# インスタンス変数にアクセス
インスタンス名.インスタンス変数名

# メソッドを使う
インスタンス名.メソッド名()

今回は覚える内容が多かったと思いますが、オブジェクト指向言語にとってクラスはとても重要な機能になります。何度も読み返してしっかりと覚えましょう!

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』