sec05 - 序章:Pythonモジュールとパッケージ入門:Fortune Cookieアプリで学ぶコード整理の基本
スポンサーリンク

モジュールとパッケージの世界へようこそ

このセクションでは、Pythonの「モジュール」と「パッケージ」について学んでいきます。

今回のゴールは、「Fortune Cookie(フォーチュンクッキー)」という、簡単なランダムメッセージ出力アプリを作ることです。実行すると、あなたの今日の運勢を“フォーチュンクッキー風”に教えてくれるという、ちょっとしたおみくじのようなプログラムです。

そして、このアプリの特徴は「多言語対応」です。最初は英語と日本語の2つの言語をサポートします。たとえば、ユーザーが「日本語」を選べば「大吉!最高の一日になりそうです!」のように表示され、「英語」を選べば「Great Fortune! A wonderful day awaits you.」というように出力されます。

このように言語ごとに異なるメッセージを用意する場合、すべてを1つのファイルに書いてしまうと、コードがすぐに煩雑になります。ですので、この講座では、「モジュール」と「パッケージ」を使って、コードを分けて管理する方法を学びます。

モジュール・パッケージとは何か?

Pythonでは、プログラムを機能ごとにファイルとして分け、そのファイルを再利用できるようにする仕組みがあります。この仕組みを理解するうえで、次の2つの言葉を押さえておきましょう。

  • モジュール(module):Pythonの1つのファイル(例:fortune.py, language_en.py など)。中に関数やクラス、グローバル変数などが入っています。たとえば「英語のメッセージを管理するためのデータ」だけを管理するモジュールを作る、というイメージです。
  • パッケージ(package):モジュールをまとめたフォルダ(ディレクトリ)のことです。フォルダの中に__init__.pyという特別なファイルを置くことで、そのフォルダを“パッケージ”として認識させます。

つまり、モジュールは“部品”であり、パッケージは“部品の入れ物”です。この2つを理解すれば、複雑なプログラムでも整理された構造で管理できるようになります。

スポンサーリンク

まずは1ファイルで作る

では、最初にfortune.pyという1つのファイルだけで、簡単なFortune Cookieアプリを作ってみましょう。

# fortune.py
import random


def main():
    # 言語を選択
    lang_code = input('言語を選んでください (jp/en): ')

    # 言語コードに応じて表示させる文字を切り替える
    if lang_code == 'en':
        # messages はアプリ内で使う文言をdictでまとめたもの
        messages = {
            'app_title': 'Fortune Cookie',
            'prompt_open': 'Would you like to open a cookie? (y/n): ',
            'fortune_prefix': 'Your fortune for today is:',
            'goodbye': 'See you tomorrow with more luck!'
        }
        # fortunes はランダムに表示する運勢のlist
        fortunes = [
            'Great Fortune! A wonderful day awaits you.',
            'Fair Fortune. Keep steady progress.',
            'Little Fortune. Stay patient and try again.',
            'Bad Fortune... but tomorrow is another chance.'
        ]
    else:  # 'jp' or else
        # messages はアプリ内で使う文言をdictでまとめたもの
        messages = {
            'app_title': 'フォーチュンクッキー',
            'prompt_open': 'クッキーを開きますか? (y/n): ',
            'fortune_prefix': 'あなたの今日の運勢は:',
            'goodbye': 'また明日も幸運を!',
        }

        # fortunes はランダムに表示する運勢のlist
        fortunes = [
            '大吉!最高の一日になりそうです!',
            '中吉。ちょっとした幸運が訪れるでしょう。',
            '小吉。小さな努力が実を結びます。',
            '凶...でも心配しすぎないでください。'
        ]

    # クッキーを開きますか?
    print(f"=== {messages['app_title']} ===")
    answer = input(messages['prompt_open'])

    if answer == 'y':
        print(f"{messages['fortune_prefix']} {random.choice(fortunes)}")
    else:
        print(messages['goodbye'])


main()

このコードを実行すると、指定した言語に応じてランダムなメッセージが表示されます。たとえば、言語を"en"にすれば英語のメッセージが、"jp"にすれば日本語のメッセージが表示されます。

random.choice

47行目のrandom.choiceは、引数として渡されたlistからランダムに1つの要素を取り出す関数です。import randomrandomモジュールをインポートし、使用します。

改良方針:ファイルを分けて整理しよう

このコードは、今のところ1つのファイルで完結していますが、問題があります。それは、「すべての情報がfortune.pyに詰め込まれている」ことです。

例えば、今後このアプリに新しい言語(たとえばフランス語やスペイン語)を追加したい場合、fortune.pyの中に新しい言語の情報をどんどん追加していく必要があります。すると、ファイルの行数がどんどん増えていき、どの部分がどの言語の設定なのかが分かりにくくなります。

また、メッセージを修正したいときにも、fortune.pyを直接開いて編集する必要があります。これでは、言語担当者(翻訳者など)とプログラム担当者が作業を分けることも難しくなってしまいます。

そこで、「言語ごとにファイルを分ける」という整理方法を採用します。たとえば、次のようなフォルダ構成にすることで、プログラムの見通しが格段によくなります。また、使用する言語を管理するためのモジュールも作っていきます。

fortune_cookie/
├─ fortune.py  # メインの実行用ファイル
└─ manager/
    ├─ __init__.py          # パッケージ化用
    └─ language_manager.py  # 使用する言語を管理する
└─ message/
    ├─ __init__.py     # パッケージ化用
    ├─ language_en.py  # 英語メッセージ
    └─ language_jp.py  # 日本語メッセージ

こうすることで、fortune.pyには「どのモジュールを使うか」という最低限のロジックだけを残し、言語データはそれぞれの専用ファイルに分離できます。

次のレクチャーから、このfortune.pyのコードを、少しずつファイルに分けていき、「モジュール」と「パッケージ」の考え方を身につけていきましょう。

言語管理について

このセクションでは「モジュール」と「パッケージ」に重点を置いているため、Pythonファイルを用いた言語管理について解説を行います。(language_jp.py, language_en.pyを使って言語管理します。)

しかし、実際のアプリケーションで言語を管理する際は、翻訳者がExcelなどのファイルを編集し、そのデータを取り込んで使用するのが一般的です。Excelには、主要言語とその他の言語を一覧形式で表示できる利点があり、読みやすく編集しやすい特徴があります。また、翻訳者はプログラマーではないので、Pythonファイルを直接編集するのはリスクが伴います。

ですので、このセクションの解説は、言語管理において必ずしもベストな方法ではないことにご留意ください。

スポンサーリンク