2022年8月16日火曜日

Python で class の中に class を定義する方法とメリット

Python で class の中に class を定義する方法とメリット

概要

Python では内部クラスを定義することができます
簡単な使い方の紹介とメリットを紹介します

環境

  • macOS 11.6.8
  • Python 3.10.2

内部クラスを使わない場合

  • vim team.py
class Team():

    def __init__(self, team_name: str):
        self.team_name = team_name


class Coach():

    def __init__(self, name: str):
        self.name = name


class Player():

    def __init__(self, name: str):
        self.name = name
  • vim team1.py
from team import Team, Player, Coach

class Team1(Team):

    def __init__(self, team_name: str):
        super().__init__(team_name)
        self.player = Player("p1")
        self.coach = Coach("c1")

    def show_name(self):
        print(self.team_name)
        print(self.player.name)
        print(self.coach.name)


if __name__ == '__main__':
    team1 = Team1("team1")
    team1.show_name()
  • python team1.py
team1
p1
c1

内部クラスを使う場合

  • vim team.py
class Team():

    def __init__(self, team_name: str):
        self.team_name = team_name


    class Coach():

        def __init__(self, name: str):
            self.name = name


    class Player():

        def __init__(self, name: str):
            self.name = name
  • vim team1.py
from team import Team

class Team1(Team):

    def __init__(self, team_name: str):
        super().__init__(team_name)
        self.player = self.Player("p1")
        self.coach = self.Coach("c1")

    def show_name(self):
        print(self.team_name)
        print(self.player.name)
        print(self.coach.name)


if __name__ == '__main__':
    team1 = Team1("team1")
    team1.show_name()

結果は同じです

考察

内部クラスを使った場合 Player と Coach クラスを import する必要がなくなります
これが一番のメリットで例えば Player と Coach クラスをいろいろな場所で使う場合にはいろいろな場所に import 文を書かなくてはいけません
しかし内部クラスにすることで親クラスを継承するだけで使えるようになるので毎回 import を書かなくて済みます
親クラスを継承していれば内部クラスは使えるので単純に self で参照することで使えます

デメリットとしては内部クラスとして定義したクラスを他のモジュールから import することができない点です
必ず親クラスである Team クラスを継承することが前提になるので例えば Coach クラスだけを使いのにわざわざ Team クラスを継承するように書かなければいけないのは面倒になります

個人的には必ず継承するような共通クラスを作るような場合には内部クラスをガンガン使っていいかなと思っています
ただ内部クラスの全部を使うわけではなく一部を使いたいというケースでは微妙で内部クラスとして定義したクラスは使っていてもいなくてもメモリ展開はされてしまうので余計なリソースを使いたくない場合には使用しないほうがいい場合もあります

内部クラスから親クラスのメソッドなどを self を介してアクセスすることはできないのでそこも注意が必要です
もし親クラスにアクセスしたい場合には親クラスをDIする必要があります

0 件のコメント:

コメントを投稿