python_learn

2-9:ファイル分け

前ページ(2-8:クラス) | 目次へ戻る | 次ページ(2-10:モジュール・パッケージ・ライブラリ)


クラスまでやってきましたが、さらに複雑な処理になるとクラスの数も多くなっていきます。

そうなると一つのファイルのみにソースコードを書いていると何万行などになってしまう場合があります。

そうなると管理やメンテナンスが大変になるので、ソースコードをファイル分けしていきます。

ファイル分けの方法

まずは分ける前のファイルとして以下を準備します。

・2-09_01_test_class.py

# 「SumClass」というクラスを作成
class SumClass:
    # クラス定数
    CONST_NUMBER = 1000

    # コンストラクタ
    def __init__(self):
        # コンストラクタはクラスオブジェクトが作成されるときに呼ばれる
        self.add1 = 0
        self.add2 = 0
        print("constructor called")

    def set_number(self, a, b):
        # クラス変数に値を代入
        self.add1 = a
        self.add2 = b

    def calc_sum(self):
        # 計算結果を返す
        return self.add1 + self.add2

    def show_set_number(self):
        # 設定されているクラス変数の値を表示
        print("add1: ", self.add1)
        print("add2: ", self.add2)


# メイン関数
def main():
    sc = SumClass()
    sc.set_number(5, 8)  # 足したい数を設定
    print(sc.calc_sum()) # sc1の足し算の結果を表示
    sc.show_set_number() # クラス変数に設定された値を確認

if __name__ == '__main__':
    main()

「2-08_01_class_test.py」の内容とほぼ同じ感じですが、「if __name__ == ‘__main__’:」やメイン関数の記述を追加しています。

・if __name__ == ‘__main__’:

「if __name__ == ‘__main__’:」についてですが、これはPythonのソースコードのファイルが呼ばれた時、つまり「python xxx.py」のコマンドが実行された時に一番最初に呼ばれます。

その後にmain()とあるので、Pythonのソースコードが呼ばれた後にはmain関数が実行されることになります。

・main関数

main関数はその名前の通りメインとなる関数です。基本的に何か処理を行う際にはこのmain関数を基準としてそこから関数を呼び出したりオブジェクトを作成したりして処理を行います。

main関数は短い方が好ましいとされているので、複雑な処理はmain関数には書かずに関数に分けたりクラスに任せたりしましょう。

ファイル分けを行う前の解説はここまでにして、実際にファイル分けをしていきます。

ファイル分けの考え方

基本的には「クラス単位でファイルを分ける」のが一般的です。ちゃんとしたクラス分けがされていれば、クラス毎に機能がまとまっているためファイルに分けても問題がないためです。

実際にファイルに分けると以下のようになります。

・sum_class.py

#
# sum_class.py
#
class SumClass:
    # クラス定数
    CONST_NUMBER = 1000

    # コンストラクタ
    def __init__(self):
        # コンストラクタはクラスオブジェクトが作成されるときに呼ばれる
        self.add1 = 0
        self.add2 = 0
        print("constructor called")

    def set_number(self, a, b):
        # クラス変数に値を代入
        self.add1 = a
        self.add2 = b

    def calc_sum(self):
        # 計算結果を返す
        return self.add1 + self.add2

    def show_set_number(self):
        # 設定されているクラス変数の値を表示
        print("add1: ", self.add1)
        print("add2: ", self.add2)

・2-09_02_main.py

# 同じフォルダ内のsum_class.pyを読み込んでscと記述できるようにする
import sum_class as sc

# メイン関数
def main():
    sc_obj = sc.SumClass()
    sc_obj.set_number(5, 8)  # 足したい数を設定
    print(sc_obj.calc_sum()) # sc1の足し算の結果を表示
    sc_obj.show_set_number() # クラス変数に設定された値を確認

if __name__ == '__main__':
    main()

実際に動作を確かめる場合は、同じフォルダ内に「2-09_02_main.py」と「sum_class.py」を配置して「2-09_02_main.py」の方を実行してみてください。

すると以下のようにちゃんとsum_class.pyにあるSumClassを使った結果が表示されます。

python 2-09_02_main.py

constructor called
13
add1:  5
add2:  8

「2-09_02_main.py」について少し解説すると「import sum_class as sc」のところで「sum_class.py」ファイルを読み込んでいます。

意味としては「import sum_class」で「sum_class.py」というファイル名を同じフォルダ内から探して読み込んでいます。

そして「as sc」というところで読み込んだsum_classファイルの内容を「sc」と略して記述できるようにしています。

なので「import sum_class as sc」とは「同じフォルダ内にあるsum_class.pyファイルの内容を読み込み、scと略して記述できるようにする」という意味になります。

ちなみに以下のようにサブフォルダ内にあるファイルを読み込みたい場合は、importの前に「from [フォルダ名]」を付けます。

learn_python
  2-09_03_main2.py

└─folder
        sum_class.py

・2-09_03_main2.py

# folderというサブフォルダ内のsum_class.pyを読み込んでscと記述できるようにする
from folder import sum_class as sc

# メイン関数
def main():
    sc_obj = sc.SumClass()
    sc_obj.set_number(5, 8)  # 足したい数を設定
    print(sc_obj.calc_sum()) # sc1の足し算の結果を表示
    sc_obj.show_set_number() # クラス変数に設定された値を確認

if __name__ == '__main__':
    main()

ファイル分けの利点

ファイルを分けることの最大の利点は「複数人でソースコードを書ける」ことです。

ファイルを分けていなければ、誰かがソースコードを書いている時に他の人は何もできません。しかしファイル分けをしていれば、複数人で同時に開発を行うことができます。

またファイル毎にちゃんと機能を分けることができていれば管理やメンテナンスもしやすくなります。

個人でちょっとしたものを作成する程度であれば問題にはなりませんが、ソースコードが長くなってきた場合や複数人で開発をしなければならない時は必ず適切なファイル分けをするようにしましょう。

練習問題

2-8:クラスの練習問題で作成したものをクラス分けしてみてください。

解答例

※今回は同フォルダ内に配置することを前提の例として解答している。

・student.py
#
# student.py
# 
class Student:
    SUBJECT_NUM = 3 # 教科数

    # コンストラクタ
    def __init__(self, name, language, english, math):
        # 名前と点数を引数として各値をクラス変数に設定
        self.name = name
        self.language = language
        self.english = english
        self.math = math

    # 合計点を計算
    def calc_sum(self):
        return self.language + self.english + self.math

    # 平均点を計算
    def calc_average(self):
        return self.calc_sum() / self.SUBJECT_NUM

    # 名前と合計、平均を表示(今回はまとめているがまとめなくてもよい)
    def show_data(self):
        sum_point = self.calc_sum()
        average_point = self.calc_average()

        message = "[" + self.name + "] sum: "
        message = message + str(sum_point) + " average: "
        message = message + str(average_point)

        print(message)

・2-09_04_file_practice.py

import student as st

# メイン関数
def main():
    # 各生徒のオブジェクトを作成
    sato = st.Student("Sato", 63, 42, 78)
    sasaki = st.Student("Sasaki", 33, 98, 42)
    miura = st.Student("Miura", 13, 62, 89)

    # 各オブジェクト毎の名前、合計、平均を計算して表示
    sato.show_data()
    sasaki.show_data()
    miura.show_data()

if __name__ == '__main__':
    main()


前ページ(2-8:クラス) | 目次へ戻る | 次ページ(2-10:モジュール・パッケージ・ライブラリ)