0
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonのクラスについての知識をまとめてみた

Posted at

Pythonのクラスについての理解が浅いため、業務で活用できるよう勉強した。勉強資料としては主にYouTubeと公式ドキュメントを使用した。(参照

目次

(1)クラスとは
(2)クラスの表現
(3)Constructorの実装
(4)Finalizerの実装
(5)継承
(6)クラスメソッド
(7)スタティックメソッド

1. クラスとは

クラスとは、概念として存在するオブジェクトをインスタンスとして実際に作成するための仕組みである。
クラスの説明をするときは、よく鯛焼き機が例に出される。クラスの概念を鯛焼き機の例に当てはめると以下のようになる。

オブジェクト 鯛焼きという概念
クラス 鯛焼き機
インスタンス 鯛焼き

とにかく、クラスという設計図を作成することで、その設計図のルールに則ったインスタンスという実態を簡単に作成できるようになる。

2. クラスの表現

クラスは「データ」と「処理」によって表現される。
Pythonではこれらのことを特に「クラス変数、インスタンス変数」「メソッド」と呼ぶ。

Pythonでの呼び方 説明
データ クラス変数 クラス内で定義された変数
データ インスタンス変数 インスタンス内で定義された変数
処理 メソッド クラス内で定義された関数

それでは、実際にクラスを定義してみる。

クラスの定義
class Taiyaki: #クラスを定義

    feature = "oishii!!" #クラス変数を定義
    
    def get_price(self,price,tax): #メソッドを定義
        print(price*tax)

t_1 = Taiyaki() #インスタンス化

print(t_1.feature)
# > oishii!!

t_1.store = "shibuya" #アトリビュートを定義
print(t_1.store)
# > shibuya

t_1.get_price(150,1.08) #メソッド実行
# > 162.0

クラスを定義

class Taiyaki: #クラスを定義

classに続いてクラス名を記述することでクラスTaiyakiが定義される。

クラス変数を定義

class Taiyaki: #クラスを定義

    feature = "oishii!!" #クラス変数を定義

print(t_1.feature)
# > oishii!!

クラス変数は全てのインスタンスで共有される。インスタンスから呼び出す場合、t_1.featureと()無しで記述すれば良い。

アトリビュートを定義

t_1.store = "shibuya" #アトリビュートを定義
print(t_1.store)
# > shibuya

アトリビュートは各インスタンスに対して定義する。インスタンスt_1にアトリビュート名storeを繋ぎ、変数を代入する。
このようにインスタンスを作成するたびにアトリビュートを定義するのは、かなり面倒である。
この問題を解消するメソッドとしてConstructorというものがある。Constructorの概要については後述を参照してほしい(3. Constructorの実装)。

クラス変数とインスタンス変数で同じ名前を使用した場合、インスタンス変数が優先される。

メソッドを定義

def get_price(self,price,tax): #メソッドを定義
    print(price*tax)

メソッドは、関数と同様にdefで書き始めて定義する。
ほとんど関数と同様の構造であるが、注意点として、メソッドの引数にはselfを記述しなければならない。selfとはインスタンス自身のことである。つまり、t_1.price()t_1.price(t_1)という実行内容を省略したものになる。私たちは普段意識していないだけで普段からこのようにインスタンスを省略してメソッドを使用している。Pythonの組み込み関数を使用して例を挙げる。

組み込み関数
sum([1,2,3])
# > 6

a_list = [1,2,3]
a_list.sum()
# > 6

sum()は本来、括弧内の第一引数の数値列を合計するものである。しかし、インスタンスを通して呼び出したときは、そのインスタンスを計算対象として扱う(つまりselfを第一引数として扱う)と考えるように実行される。このとき、a_list.sum(a_list)と書くと見づらいため、引数となるインスタンスは省略して良い、という仕様になっている。
まとめると、Pythonではメソッド内でselfを定義することで引数にオブジェクトを書く手間を省くことができる。

3. Constructorの実装

Constructorとは、メソッドの一種であり、__init__()というメソッド名で定義する。このメソッドは、インスタンスを作成したときに自動で呼び出されるため、クラスの初期設定に有用である。
先ほど作成したクラスTaiyakiにConstructorを追加すると下記のようになる。

class Taiyaki: #クラスを定義

    def __init__(self,name): #Constructorを定義
        self.name = name
    
    def get_price(self,price,tax): #メソッドを定義
        print(price*tax)

t_1 = Taiyaki("shibuya") #インスタンス化
print(t_1.name)
# > shibuya

前述の通り、Constructorはインスタンス化と同時に自動で呼び出されるため、コンストラクタ実行に引数が必要な場合はインスタンス自体にその引数を設定する必要がある(Taiyaki("shibuya"))。

4. Finalizerの実装

Finalizerとは、メソットの一種であり、__del__()というメソッド名で定義する。このメソッドはインスタンスを削除するためのメソッドである。

class Taiyaki: #クラスを定義

    def __init__(self,name): #Constructorを定義
        self.name = name
    
    def get_price(self,price,tax): #メソッドを定義
        print(price*tax)
    def __del__(self): #Finalizerを定義
        print("---called del---")

t_1 = Taiyaki("shibuya") #インスタンス化
del t_1 #Finalizer実行
# > ---called del---

5. 継承

継承とは、あるクラスの機能を受け継ぎながら、新しいクラスを定義することである。ここではそれぞれ親クラス、子クラスと呼ぶが、呼び方は色々ある。

呼び方
継承元のクラス 親クラス、基底クラス、スーパークラス
継承先のクラス 子クラス、派生クラス、サブクラス

これによって、既存のクラスと類似しているが僅かに異なる機能を持ったクラスを作成したいときに便利である。
例えば、Taiyakiクラスを親クラスとして、Ohbanyakiクラスという子クラスを作成してみよう。

class Taiyaki: #クラスを定義

    def __init__(self,name): #Constructorを定義
        self.name = name
    
    def get_price(self,price,tax): #メソッドを定義
        print(price*tax)

class Ohbanyaki(Taiyaki): #Taiyakiクラスの継承
    def get_area(self):
        print(3.14*3**2)

    
t_1 = Taiyaki("shibuya") #インスタンス化
o_1 = Ohbanyaki("shibuya")
print(o_1.get_price(200,1.08)) #親クラスのメソッドを使用
print(o_1.get_area()) #子クラスのメソッドを使用

メソッドのオーバーライド

親クラスのメソッドと同じ名前のメソッドを子クラスで定義した場合、「メソッドのオーバーライドをする」と表現する。
例を示した上で挙動について説明する。

class Taiyaki: #クラスを定義
    def __init__(self,name,area): #Constructorを定義
        self.name = name
        self.area = area
    
    def get_price(self,price,tax): #メソッドを定義
        print(price*tax)

class Ohbanyaki(Taiyaki): #Taiyakiクラスの継承
    def __init__(self, name, radius) #メソッドのオーバーライド
        self.name = name
        self.radius = radius
    def get_area(self):
        print(3.14*self.radius**2)

o_1 = Ohbanyaki("shibuya",3) #インスタンス化
o_1.get_area()
# > 28.26

この場合、子クラスOhbanyakiのインスタンスを作成したときに、親クラスの__init__()ではなく、オーバーライドした子クラスの__init__()が参照される。

注意
オーバーライドされた親クラスのメソッドは、子クラスのインスタンスでは一切使えない。
オーバーライド元のメソッド内容を継承したいときはsuper関数を用いる。

class Taiyaki: #クラスを定義
    def __init__(self,name,area): #Constructorを定義
        self.name = name
        self.area = area
        
class Ohbanyaki(Taiyaki): #Taiyakiクラスの継承
    def __init__(self, name, area) #メソッドのオーバーライド
        super().__init__(name,area)
        print(self.name)
        print(self.area)

6. クラスメソッド

クラスメソッドとは、インスタンスを作成しなくても実行できるクラス内のメソッドのことである。
例を示した上で挙動について説明する。

class Taiyaki: #クラスを定義

    feature = "oishii!!"

    @classmethod #以下のメソッドをクラスメソッドに変更するデコレータ
    def add_feature(cls): #クラスメソッドを定義
        cls.feature += "_taiyaki!!"
        return cls.feature

print(Taiyaki.add_feature())
# > oishii!!_taiyaki!!

t_1 = Taiyaki()
print(t_1.add_feature()) #インスタンスからクラスメソッドを呼び出すことも可能
# > oishii!!_taiyaki!!

メソッド作成時にインスタンス自身のselfを引数に記述したのと同様に、クラスメソッド作成時にはクラス自身を表すclsを引数に記述する必要がある。
また、インスタンスからクラスメソッドを呼び出すことも可能である。クラスメソッドはクラスに対する処理であるため、どのようなインスタンスから呼び出しても同じ結果が得られる。

クラスメソッドはデコレータの一種である。

7. スタティックメソッド

スタティックメソッドは、クラスメソッドと同じくインスタンスを作成しなくても実行できるメソッドである。クラスメソッドと異なる点として、クラス自身を表すcls引数やインスタンス自身を表すselfを引数を受け取らないことである。つまり、実質的な動作内容としては関数と変わらない。
下記に実装例を示す。

class Taiyaki: #クラスを定義
    def __init__(self,name,area): #Constructorを定義
        self.name = name
        self.area = area
        
    @staticmethod #以下のメソッドをスタティックメソッドに変更するデコレータ
    def multi(x,y): #スタティックメソッドを定義
        return x*y

    @staticmethod #以下のメソッドをスタティックメソッドに変更するデコレータ
    def call_name(): #スタティックメソッドを定義
        print(Taiyaki.name)

print(Taiyaki.multi(3*4))
# > 12

このように、スタティックメソッドの引数にはselfclsを入れない。そのため、もしスタティックスタック内でクラス変数を使用したい場合は Taiyaki.nameのようにクラス名から呼び出す必要がある。

スタティックメソッドはデコレータの一種である。

参照

Python 3.12.2 documentation

【徹底解説】Pythonのクラスの基本からクラス継承やクラス変数などまでわかりやすく|クラスの使い方も解説【Python入門・応用21】

【脱オブジェクト指向初心者!】Pythonの継承の基礎を学ぼう

0
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?