[Pythonのはじめ方] Part13: 自作モジュールの作成とインポート

はじめに:モジュールって何?

Pythonプログラミングを進めていくと、コードがどんどん長くなってきますよね。そんなとき、関連する関数やクラスを別のファイルにまとめておくと、コードが整理されて見やすくなります。この「まとめられたファイル」のことをモジュールと呼びます。

これまでのステップで、mathdatetimeといったPythonに標準で用意されている標準ライブラリのモジュールを使ってきました。今回は、自分でオリジナルのモジュールを作成し、それを別のPythonファイルから利用(インポート)する方法を学びましょう!

モジュールを使うメリットはたくさんあります:

  • コードの再利用性向上:一度作った関数などを、色々なプログラムから呼び出して使えます。
  • コードの整理:機能ごとにファイルを分けることで、どこに何が書いてあるか分かりやすくなります。
  • 保守性の向上:修正が必要な場合、該当するモジュールだけを直せば良いので、メンテナンスが楽になります。

自作モジュールの作り方

自作モジュールの作成はとても簡単です。普段Pythonのコードを書いている.pyファイル、それ自体がモジュールになれるのです!

例として、簡単な計算や挨拶をする関数を持つモジュールmy_utils.pyを作成してみましょう。

ファイル名: my_utils.py

# my_utils.py

# 二つの数を足し合わせる関数
def add(a, b):
  """二つの数を足し算して結果を返す"""
  return a + b

# 名前を受け取って挨拶する関数
def greet(name):
  """指定された名前で挨拶メッセージを返す"""
  return f"こんにちは、{name}さん!"

# 定数も定義できる
PI = 3.14159

これだけで、add関数、greet関数、そして定数PIを持つmy_utilsモジュールの完成です!

注意点: モジュール名(ファイル名)は、Pythonの識別子として有効な名前にする必要があります。数字で始まったり、ハイフン(-)を含んだりする名前は避け、英数字とアンダースコア(_)で構成するのが一般的です。

自作モジュールのインポート方法

作成したモジュールを別のPythonファイル(スクリプト)から使うには、import文を使います。先ほど作成したmy_utils.pyと同じディレクトリ(フォルダ)に、main.pyというファイルを作成して試してみましょう。

1. モジュール全体をインポートする (import)

import モジュール名 の形式で、モジュール全体をインポートします。モジュール内の関数や変数を使うときは、モジュール名.要素名のように記述します。

ファイル名: main.py

# main.py
import my_utils # my_utils.py をインポート

# my_utils モジュール内の関数や定数を使う
result = my_utils.add(5, 3)
message = my_utils.greet("Python")
pi_value = my_utils.PI

print(f"足し算の結果: {result}") # 足し算の結果: 8
print(message)                 # こんにちは、Pythonさん!
print(f"円周率: {pi_value}")      # 円周率: 3.14159

2. モジュールから特定の要素だけインポートする (from ... import ...)

モジュール内の特定の関数や変数だけを使いたい場合は、from モジュール名 import 要素名1, 要素名2, ... の形式を使います。この方法だと、要素を使うときにモジュール名を付ける必要がなくなります。

ファイル名: main.py (別パターン)

# main.py
from my_utils import add, greet # my_utils から add 関数と greet 関数をインポート

# インポートした関数を直接使える
result = add(10, 20)
message = greet("初学者")

print(f"足し算の結果: {result}") # 足し算の結果: 30
print(message)                 # こんにちは、初学者さん!

# PI はインポートしていないので、直接使うとエラーになる
# print(PI) # NameError: name 'PI' is not defined

from my_utils import * と書くと、モジュール内のすべての要素(アンダースコア_で始まらないもの)をインポートできますが、どの要素がどこから来たのか分かりにくくなるため、あまり推奨されません。

3. モジュールに別名をつけてインポートする (import ... as ...)

モジュール名が長かったり、他のモジュールと名前が衝突しそうな場合に、import モジュール名 as 別名 の形式で別名を付けることができます。標準ライブラリや外部ライブラリを使う際によく使われる方法です。

ファイル名: main.py (さらに別パターン)

# main.py
import my_utils as mu # my_utils モジュールを mu という別名でインポート

# 別名を使ってアクセスする
result = mu.add(1, 1)
message = mu.greet("エイリアス")
pi_value = mu.PI

print(f"足し算の結果: {result}") # 足し算の結果: 2
print(message)                 # こんにちは、エイリアスさん!
print(f"円周率: {pi_value}")      # 円周率: 3.14159

同様に from モジュール名 import 要素名 as 別名 のように、特定の要素に別名を付けることも可能です。

# main.py
from my_utils import greet as gr # greet 関数を gr という別名でインポート

message = gr("別名要素")
print(message) # こんにちは、別名要素さん!

モジュールはどこから探されるの? (モジュール検索パス)

import 文を実行したとき、Pythonはどのようにして目的のモジュールファイル(.pyファイル)を見つけるのでしょうか? Pythonは以下の順序でモジュールを探します。

  1. カレントディレクトリ: スクリプトを実行しているディレクトリ。今回のようにmain.pymy_utils.pyが同じディレクトリにあれば、すぐに見つかります。
  2. 環境変数 PYTHONPATH: 環境変数PYTHONPATHに設定されているディレクトリ。
  3. Pythonのインストールディレクトリ: Pythonのインストール時に設定された標準ライブラリなどが置かれているディレクトリ。

現在Pythonがモジュールを探しに行くパスのリストは、sysモジュールのsys.pathというリストで確認できます。

import sys

print(sys.path)
# 出力例(環境によって異なります):
# ['', '/usr/lib/python310.zip', '/usr/lib/python3.10', ...]
# '' はカレントディレクトリを表します。
通常、自分で作成したモジュールは、それを利用するスクリプトと同じディレクトリに置くか、後々学ぶパッケージの仕組みを使って管理することが多いです。

スクリプト実行時だけコードを動かすおまじない:if __name__ == "__main__":

モジュールファイルは、インポートして使うだけでなく、直接スクリプトとして実行することもできます(例: python my_utils.py)。

ここで一つ便利なテクニックがあります。それが if __name__ == "__main__": という構文です。

  • Pythonファイルが直接実行された場合、そのファイルの__name__という特別な変数には"__main__"という文字列が自動的に設定されます。
  • 一方、他のファイルからモジュールとしてインポートされた場合、__name__にはそのモジュール名(ファイル名から.pyを除いたもの、今回の例では"my_utils")が設定されます。

この違いを利用して、if __name__ == "__main__": のブロック内に書かれたコードは、そのファイルが直接実行されたときだけ実行されるようにできます。これは、モジュールの動作確認のためのテストコードを書くのによく使われます。

my_utils.pyに追記してみましょう。

ファイル名: my_utils.py (追記)

# my_utils.py

# (既存の関数定義は省略)
def add(a, b):
  return a + b

def greet(name):
  return f"こんにちは、{name}さん!"

PI = 3.14159

# このファイルが直接実行されたときだけ、以下のコードが実行される
if __name__ == "__main__":
  print("my_utils.py を直接実行しました!")
  
  # モジュールのテストコード
  test_result = add(100, 200)
  print(f"add(100, 200) のテスト結果: {test_result}") # 300
  
  test_greet = greet("テスト")
  print(test_greet) # こんにちは、テストさん!

この状態で、ターミナル(コマンドプロンプト)からpython my_utils.pyと実行すると、ifブロックの中のprint文やテストコードが実行されます。

しかし、main.pyからimport my_utilsとして実行した場合は、my_utils.py__name__"my_utils"になるため、ifブロックの中は実行されません。これにより、インポートしただけで余計な処理が動いてしまうのを防ぐことができます。

まとめ

今回は、自分でPythonモジュールを作成し、それを他のファイルからインポートして利用する方法を学びました。

  • Pythonの.pyファイルはそのままモジュールとして利用できる。
  • import, from ... import ..., import ... as ... など、様々なインポート方法がある。
  • Pythonは特定の検索パス(カレントディレクトリ、PYTHONPATH、インストールディレクトリ)に従ってモジュールを探す。
  • if __name__ == "__main__": を使うと、ファイルが直接実行されたときだけ特定のコードを実行できる。

モジュールを使いこなせるようになると、より複雑なプログラムも整理しやすくなり、開発効率が格段にアップします!どんどん活用していきましょう。

次は、ファイルの読み書きについて学んでいきます。お楽しみに!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です