おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

Python初級者のお勉強ノート(12)モジュール

今回は、Pythonで単語カードを管理するモジュールを作成します。 このモジュールでは、単語の追加、削除、検索、さらにクイズ形式での学習が可能です。 モジュールを作ることで、再利用性が高く、複数のプログラムで簡単に使えるコードを提供できます。

モジュールとは?

モジュールとは、Pythonコードをまとめたファイルのことです。 *.py形式のファイルをモジュールとして扱えます。 モジュールを使うと、別のPythonスクリプトから簡単に機能を呼び出せるようになります。

モジュールは通常、プロジェクト内の整理されたディレクトリに配置します。 例えば、今回のプログラムの開発がprojectディレクトリで行われているならば、そのディレクトリ内に「モジュールのファイル」も「モジュールを使うファイル」も置くようにします。

project/
    flashcard.py   # 単語カードのモジュール
    main.py        # モジュールを利用するスクリプト

flashcard.pyがモジュールファイルで、main.pyからこれをインポートして使います。

モジュール名とは?

モジュール名とは、通常は、モジュールのファイル名(拡張子.pyを除いた部分)です。 例えば、flashcard.pyというモジュールを作成した場合、そのモジュール名はflashcardです。

単語カードモジュールのコード

以下は、単語カードを管理するモジュールのコードです。コードの後に、それぞれのポイントを詳しく解説します。

import random

class FlashcardManager(dict):
    def add_card(self, word, meaning):
        if word in self:
            print(f"単語 '{word}' は既に登録されています。")
        else:
            self[word] = meaning
            print(f"単語 '{word}' を登録しました。")

    def remove_card(self, word):
        if word in self:
            del self[word]
            print(f"単語 '{word}' を削除しました。")
        else:
            print(f"単語 '{word}' は登録されていません。")

    def search_card(self, word):
        if word in self:
            print(f"単語: {word}\n意味: {self[word]}")
        else:
            print(f"単語 '{word}' は登録されていません。")

    def start_quiz(self):
        if not self:
            print("クイズを開始するには単語カードを追加してください。")
            return

        print("クイズを開始します。終了するにはCtrl+Cを押してください。")
        try:
            while True:
                word, meaning = random.choice(list(self.items()))
                print(f"単語: {word}")
                input("解答を確認するにはEnterを押してください...")
                print(f"意味: {meaning}\n")
        except KeyboardInterrupt:
            print("\nクイズを終了します。")

コードの解説

辞書型のサブクラスと「継承」

FlashcardManagerクラスは、Pythonの辞書型(dict)を継承して作られています。 dictは小文字で始まりますが、クラス名です。 組み込みのクラスは小文字で始まることが多いです。

継承とは、既存のクラス(ここではdict)をベースにして新しいクラスを作る仕組みです。 これにより、辞書型の機能(in演算子del関数など)をそのまま使いつつ、独自の機能(add_cardstart_quiz)を追加できます。

継承を用いて作られたクラスは、サブクラスと呼ばれます。

辞書型のin演算子

辞書型では、in演算子を使ってキーが存在するかどうかを判定します。 例えば、word in selfは、単語がselfに登録されているかを確認しています。 このとき、selfは辞書型のサブクラスであるFlashcardManagerクラスのインスタンスなので、辞書型の性質を受け継いでいます。 したがって、in演算子も同様に使うことができるのです。

辞書型のdel関数

delは辞書から特定のキーとその値を削除するために使います。 例えば、del self[word]は、辞書selfからキーがwordである、キーと値のペアを削除します。

random.choiceと辞書型のitemsメソッドの使い方

random.choiceはリストからランダムに1つの要素を選択します。 このコードでは、list(self.items())で辞書のキーと値のペアをリストとして取得し、その中からランダムに選んでクイズに使用しています。

辞書のitemsメソッドは、その辞書を参照するビューオブジェクトを返します。 ビューオブジェクトはその要素が必要なときに、キーと値のタプルの列を作ります。 プログラム内では、listメソッドの引数として評価されるときが、それにあたります。 listメソッドはビューオブジェクトからリストを作って返します。

例外KeyboardInterrupt

try-except構文の中でKeyboardInterruptを捕捉することで、ユーザーがクイズ中にCtrl+Cを押したときに適切に処理を終了します。

モジュールをインポートする方法

Pythonでは、import文を使ってモジュールをインポートします。
モジュールをインポートする主な方法は以下の通りです。

1. 単純にモジュールをインポートする

import flashcard

この場合、flashcard内の関数やクラスを使うときは、モジュール名を明示的に指定します。

manager = flashcard.FlashcardManager()

2. モジュールから特定の関数やクラスをインポートする

from flashcard import FlashcardManager

この方法では、指定した要素を直接使えます。

manager = FlashcardManager()

3. 別名をつけてインポートする

import flashcard as fc

これにより、モジュール名を短縮して使うことができます。

manager = fc.FlashcardManager()

モジュール内の関数やクラスの呼び出し方

単純にimportした場合

import flashcard

# モジュール名を明示的に指定
manager = flashcard.FlashcardManager()

fromを使った場合

from flashcard import FlashcardManager

# クラス名を直接使用可能
manager = FlashcardManager()

どちらを使うべきか?

  • モジュールの大部分を使う場合は、import モジュール名が適切です。
  • モジュール内の一部の要素だけを使いたい場合は、from モジュール名 import 要素名を使うとコードが簡潔になります。

モジュールの呼び出し側で押さえておくべきこと

  1. モジュールの再インポートは不要
    一度インポートされたモジュールはキャッシュされるため、再インポートは必要ありません。

  2. 名前の衝突に注意
    別のモジュールや変数と同じ名前を使うと、意図しない動作を引き起こすことがあります。
    必要に応じてエイリアスasキーワード)を活用しましょう。

  3. 依存関係の管理
    モジュールが他のモジュールに依存する場合、その依存関係が満たされていることを確認してください。

モジュールを使うコード(呼び出し側コード)

以下のコードをmain.pyとして作成します。単語を効率的に登録するため、コンマ区切りのデータを使います。

from flashcard import FlashcardManager

manager = FlashcardManager()

data = """
apple,りんご
banana,バナナ
cherry,さくらんぼ
date,ナツメヤシ
elderberry,ニワトコの実
fig,イチジク
grape,ぶどう
honeydew,ハニーデュー
kiwi,キウイ
lemon,レモン
mango,マンゴー
nectarine,ネクタリン
orange,オレンジ
papaya,パパイヤ
quince,マルメロ
raspberry,ラズベリー
strawberry,イチゴ
tangerine,タンジェリン
ugli fruit,ウグリフルーツ
vanilla,バニラ
watermelon,スイカ
xigua,シーグア(スイカ)
yellow passion fruit,イエローパッションフルーツ
zucchini,ズッキーニ
pear,ナシ
plum,スモモ
apricot,アンズ
coconut,ココナッツ
blackberry,ブラックベリー
blueberry,ブルーベリー
"""

for line in data.strip().split("\n"):
    word, meaning = line.split(",")
    manager.add_card(word.strip(), meaning.strip())

print("\n単語カードの検索:")
manager.search_card("apple")
manager.search_card("zucchini")

print("\nクイズを開始します:")
manager.start_quiz()

このモジュールの使いどころ

まだ、このモジュールは実用段階ではありませんが、将来的には次のようなことが考えられます。

  • 語学学習や資格試験の単語暗記
  • 技術用語や概念の整理
  • 日常生活での知識カード作成

これらの異なる用途のプログラムで、FlashcardManagerモジュールを活用することができます。 これは「プログラムの再利用」と呼ばれ、モジュールの重要な目的のひとつです。