Categories: Python

【Python】自作モジュールやパッケージを作ってみる

この記事では、Pythonで簡単な関数を定義した自作モジュールを作成して使ってみます。また、複数のモジュールを1つのディレクトリにまとめてパッケージ化する方法も解説します。

便利な関数やクラスはモジュールとして作っておくことで他のプロジェクトでも使い回したりすることができます。

それでは、自作モジュールを作成していきましょう!

自作モジュールの作成

では、まずは簡単に自作モジュールを作成していきましょう!

自作モジュールを呼び出すメインのPythonファイルと同じディレクトリ内にmy_module.pyという名前でファイルを作成します。

my_module.pyには、自らのモジュール名を出力するだけのfunc()関数を定義しておきます。

my_module.py

def func():
    print(__name__)

これで自作モジュールは完成です。保存し忘れには注意してください!
次はmain.pyから読み込んで使ってみましょう!

自作モジュールを使ってみる

モジュールを読み込むにはimport文を使います。

import モジュール名

import文を使ってモジュールやライブラリを読み込む方法

では、先ほど作成したmy_module.pyを読み込んで使ってみます。

main.py

import my_module

my_module.func()

実行結果

my_module

my_moduleというモジュール名が表示されてmy_module.pyfunc()関数が呼び出せたのがわかります。

モジュールが同じディレクトリ以下にない場合

読み込みたいモジュールが同じディレクトリ以下にない場合、先ほどと同じ方法では読み込むことができません。

なぜ同じディレクトリ以下にないと読み込めないかというと「モジュールはこっから読み込むよ!」というパスがあらかじめ設定されていて、それらのパス以外の場所はそもそも検索対象に入っていないから読み込めないんですね。

ということは、パスさえ追加すればそこからモジュールを読み込めるということです。検索して欲しい場所がある場合はパスを追加しちゃいましょう!

パスの確認

まずは、現在設定されているパスを確認してみましょう!
パスはsysモジュールのpathリストから確認できます。

main.py

import sys

for path in sys.path:
    print(path)

実行結果

/Users/user/Desktop/Python
/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python39.zip
/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9
/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload
/Users/user/Library/Python/3.9/lib/python/site-packages
/usr/local/lib/python3.9/site-packages

いろいろパスが出てきましたが注目するべきは/Users/user/Desktop/Pythonです。このパスがあるから先ほど作成したモジュールは読み込めていたんですね。

起動時に初期化された後、リストの先頭 (path[0]) には Python インタプリタを起動したスクリプトのあるディレクトリが挿入されます。スクリプトのディレクトリがない (インタプリタが対話セッションで起動された時や、スクリプトを標準入力から読み込んだ場合など) 場合、 path[0] は空文字列となり、Python はカレントディレクトリからモジュールの検索を開始します。スクリプトディレクトリは、 PYTHONPATH で指定したディレクトリの 前 に挿入されますので注意が必要です。
引用先: sys.path - sys --- システムパラメータと関数 — Python ドキュメント

パスの追加

それでは、先ほど作成したモジュールを適当な場所に移動して読み込めるようにパスを追加してみます。ここでは、簡単にデスクトップに移動しました。

import sys

# パスの追加
sys.path.append('/Users/user/Desktop')

import my_module

my_module.func()

実行結果

my_module

読み込むことができましたね!
でも無闇にパスを追加するのは危険なので本当に必要な時のみ使用しましょう!

パッケージ化

複数のモジュールを作成した場合、1つのディレクトリにまとめて管理したい時があります。そんな時はモジュールをパッケージ化しましょう!

パッケージとは、モジュールをまとめたディレクトリのことを言います。

それでは、パッケージを作成してみましょう。例として同じディレクトリ内にmy_modulesディレクトリを作成し、その中に3つのファイルを作成します。

__init__.pyは、パッケージに必要なファイルでとりあえず中身は空で問題ありません。残りのファイルには、先ほど使った自身のファイル名を出力するfunc()関数を定義しておきます。

mod1.py, mod2.py

def func():
    print(__name__)

そしたら、以下のようにmain.pyでインポートして使います。

import my_modules.mod1, my_modules.mod2

my_modules.mod1.func()
my_modules.mod2.func()

実行結果

my_modules.mod1
my_modules.mod2

以下のようにfromを使ってインポートすることもできます。

from my_modules import mod1, mod2

mod1.func()
mod2.func()

実行結果

my_modules.mod1
my_modules.mod2

パッケージのインポート

パッケージをインポートしてもそこからモジュールを呼び出すことができません。

import my_modules

my_modules.mod1.func()

実行結果

Traceback (most recent call last):
  File "/Users/user/Desktop/Python/main.py", line 3, in 
    my_modules.mod1.func()
AttributeError: module 'my_modules' has no attribute 'mod1'

そんなときに使うのが __init__.py です!
このファイルは、パッケージがインポートされた際に実行されます。

__init__.py

print('my_modulesがインポートされました!')

main.py

print('開始')

import my_modules

print('終了')

実行結果

開始
my_modulesがインポートされました!
終了

なので__init__.pyでは、最初に必ず行いたい処理やパッケージがインポートされた際に一緒にインポートするモジュールなどを記述します。

__init__.py

# パッケージがインポートされたらmod1,mod2をインポートする
import my_modules.mod1
import my_modules.mod2

main.py

import my_modules

my_modules.mod1.func()
my_modules.mod2.func()

実行結果

my_modules.mod1
my_modules.mod2

これでパッケージからモジュールを呼び出すことができるようになりました!

まとめ

この記事では、自作モジュールの使い方を解説しました。

Pythonにはライブラリが豊富に用意されているので自作モジュールを使う機会はそれほど多くないかもしれませんが、もし欲しい機能のモジュールがない場合は頑張って実装してみてください!

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

View Comments

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago