ちょっとしたプログラムを作る程度なら、それほど気にする必要はありませんが、自作ライブラリと複数のプログラムファイルで構成されたPythonアプリケーションを作成する場合、フォルダ構成が非常に重要になります。
厄介なことに、人によって(記事によって)推奨されるフォルダ構成が微妙に異なり、あるサイトでは非推奨の例として記載されていたりします。
今回はPythonでWebアプリ開発で使われるようなフレームワークは除き、一般的なPythonプログラムでアプリケーションを構築する場合におて、他の記事を参考にしながら私がベストだと思うフォルダ構成を紹介したいと思います。
まず、プログラムの実行を考える
Pythonプログラムの実行方法としては、大きく次の3通りが考えられます。
- Python.exe に実行したいプログラムを引数として渡す
- Python Prompt、又はVSCodeなどの実行ツールを使ってプログラムを実行する
- PythonプログラムをEXEファイルに変換して実行する
今回は、1の「Python.exeに実行したいプログラムを引数として渡す」方法を前提にフォルダ構成を考えたいと思います。
一言で「Python.exeに実行したいプログラムを引数として渡す」と言っても、この方法には更に2通り(-mオプションの有無)の指定方法がありますが、今回は「Python.exe -m プロジェクト名」という呼び出し方法を前提とします。
-m オプションは、続けて指定されたモジュール名を環境変数を手繰って探し出し、実行するためのものです。
ここにフォルダを指定すると、それをパッケージとしてフォルダ検索を行い、見つかったパッケージ内の __init__.py、 __main__.py を実行してくれます。
-m オプションを付けない場合は、__init__.py は実行されず、__main__.py だけが実行されます。
推奨するフォルダ構成
Pythonのアプリケーションにおいては、次のように -m オプションを使って実行する方法が一般的です。
python.exe -m プロジェクト名
プロジェクト名とは、そのアプリケーションに関するプログラムやドキュメント一式が格納されたフォルダの事です。
言い換えると、プロジェクト名でフォルダを作成し、そこに関係する全てのファイルを格納するということが推奨されています。
具体的には次のようなフォルダ構成になります。
プロジェクト名フォルダの中に、さらにプロジェクト名フォルダがありますが、どうもこれに関しても賛否両論あるようですが、多数派はこの形の様です。
自作ライブラリ(自作パッケージ)を格納するフォルダについても、2階層目の「プロジェクト名」フォルダにしか置いては行けない派と、他のプロジェクトと流用するものは1階層目の「プロジェクト名」フォルダ直下に置いてよいとする派があるようです。
私としては、他のプロジェクトと共通で使う場合においては、1階層目の「プロジェクト名」フォルダ直下に置いても良いのではないかと思っています。
フォルダ名 | 解説 | 命名 |
---|---|---|
プロジェクト名(第1階層) | このフォルダ直下に関連する全てのプログラムやファイルを格納 | 任意 |
プロジェクト名(第2階層) | アプリケーションプログラムのソースコード一式を格納 | 任意 |
libs(プロジェクト名第1階層直下) | 今回のプロジェクト用に作成したモジュール(ライブラリ)を格納 importするには環境変数の設定が必要 | 任意 |
libs(プロジェクト名第2階層直下) | 他のプロジェクトでも共通に使うモジュール(ライブラリ)を格納 importするには環境変数の設定が必要 | 任意 |
config | 各種設定ファイルを格納 | 任意 |
logs | アプリケーションが出力するログファイルを格納 | 任意 |
docs | プロジェクトに関するドキュメント一式を格納 マークアップ言語、マークダウン言語での記述が一般的 | 固定 |
tests | テストコードを格納 | 固定 |
README.md | プロジェクトに関する説明をマークダウン言語で書くのが一般的 | 任意 |
requirements.txt | pip コマンドで必要なモジュールを一括インストールする際に使用 | 任意 |
LICENSE | ライセンス条項につて記載したドキュメント | 任意 |
プロジェクトによっては、今回紹介したフォルダ以外のものが必要になるケースもあります。
例えば、下記の様なフォルダです。
フォルダ名 | 解説 | 命名 |
---|---|---|
data | 各種データの格納先 | 任意 |
csv | CSVの格納先 | 任意 |
examples | プログラム使用例の格納先 | 任意 |
sample | サンプルプログラムの格納先 | 任意 |
venv | 仮想環境の格納先 | 任意 |
docker | dockerプロジェクトの格納先 | 任意 |
notebooks | Jupyter Notebookの格納先 | 任意 |
vscode | VScodeの設定情報の格納先 | 任意 |
重要なことは次の2点です。
・「プロジェクト名」で第一階層のフォルダを作成したら、プロジェクトに関する全てをそこに格納すること
・第一階層の「プロジェクト名」フォルダ直下にはプログラムコードを置かないことです。
フォルダ名の命名については、docs と tests というフォルダは名前を踏襲することが推奨されていますが、それ以外は自由にフォルダ名を付けても良いようです。
プログラムの格納場所
プログラムの格納場所としては、第2階層目の「プロジェクト名」フォルダにアプリケーションのプログラムソースを置きます。
もし、独自のパッケージを作りたい場合は、第2階層目の「プロジェクト名」フォルダ直下に libs 等のフォルダ名でモジュールを格納します。
必要に応じて、libs の下に更に深いフォルダを作ることも可能です。
但し、python でアプリケーションを作成する場合、実行するプログラムが置かれたフォルダ配下のプログラムファイルしか import 出来ないという制限があります。
別階層のフォルダから import したい場合は、環境変数に登録しておくか、次の記述をimpot前に実行しておく必要があります。
1 2 3 4 5 6 |
import os import sys #Pythonのパッケージを検索する対象パスのリストに、実行プログラムを起点にしたライブラリまでの相対パスを登録する。 #下記の例は、実行プログラム配下のフォルダを検索対象として追加している。 sys.path.append(os.path.join(os.path.dirname(__file__), '.')) |
import についてさらに詳しい情報が知りたい方は、「【図で解説】Pythonで自作モジュール(or パッケージ)をimportするために知っておきたいこと」の記事をご覧ください。
ちなみに、パッケージの中から別のパッケージをimportする場合は、この制約は適用されません。
フォルダ構成の具体例
以上のことを踏まえた簡単なフォルダ構成の具体例を掲載しておきます。
「python -m プロジェクト名」でプログラムを実行する場合、__main__.py にメインの処理を記述する必要があります。
小規模な場合は __main__.py だけで事足りるかもしれませんが、この具体例では main_task.py にアプリケーションの骨格が記述されており、必要に応じて sub_task.py や utility.py 、libs 配下のモジュールを呼び出すという想定になっています。
フォルダ名の付け方
Pythonの場合、モジュール(Pythonのファイル)が格納されたフォルダのことを「パッケージ」として定義しているため、フォルダの命名規則にはパッケージの命名規則が適用されます。
モジュールの名前は、全て小文字の短い名前にすべきです。読みやすくなるなら、アンダースコアをモジュール名に使っても構いません。Python のパッケージ名は、全て小文字の短い名前を使うべきですが、アンダースコアを使うのは推奨されません。
pep8-ja(Pythonコーディング規約) : https://pep8-ja.readthedocs.io/ja/latest/#id23
つまり、
- 全て小文字の短い名前にする
- 複数の単語で構成されていても、アンダースコア('_')やハイフン('-')は使わない
ということになるのですが、複数の単語で構成される場合は単語が連なって読み難くなりがちです。
実際はというと、読みやすさを優先させてアンダースコアを使う事例も多く見受けられますので、それほど強く意識する必要は無さそうです。
結局のところ、命名規則は分かりやすさを目指すためのものなので、「フォルダー名には、アンダースコアを含むすべて小文字の名前を使用する」 という考えで良いかと思います。
まとめ
今回は Python でアプリケーションを作成する場合のフォルダ構成について紹介しました。
今回は色々なサイトを調べた結果を総合して推奨フォルダ構成を提示しています。
人それぞれ好みや考え方、諸事情が異なりますので、これが正解とは言えませんが、一つの指針となったのではないかと思います。
この記事がフォルダ構成の一助になれば幸いです。
コメント