概要
Python アプリケーションからスタンドアローンで動作する実行ファイルを作成する方法について紹介します。Python はインタープリタ方式で動作する言語のため、通常、実行する PC には予め Python インタプリタや必要なライブラリをインストールしておく必要があります。実行ファイルにすることで、スタンドアローンで動作させることができるようになるため、Python で作成したアプリケーションを配布したい場合にこの方法が便利です。パッケージ化するにはいくつかの方法がありますが、今回は Pyinstaller を使用する方法について紹介します。
Pyinstaller
Pyinstaller は Python のアプリケーション及び利用している依存ライブラリやデータをまとめて、1つのパッケージにするツールです。ユーザーはパッケージ化された実行ファイル単体でアプリケーションを動かすことができます。Windows、Mac OS、Linux に対応しています。
インストール
pip コマンドでインストールできます。
pip install -U pyinstaller
基本的な使い方
pyinstaller にエントリポイントが記載された Python スクリプトのパスを指定して、実行します。
pyinstaller main.py
main.py
def main():
print("Hello World")
input("Press to any key to exit.") # 終了させないため
if __name__ == "__main__":
main()
実行すると、以下のようなディレクトリが作成されます。
- build/<スクリプト名>/ : ビルドの中間ファイルが出力されるディレクトリです。
- <スクリプト名>.spec : ビルド設定が記載されたファイルです。
- dist/<スクリプト名>/: 実行ファイルを含むパッケージに必要なファイルが出力されるディレクトリです。配布する際は、このディレクトリごと配布します。
├─ main.py
├─ main.spec
├─ build
│ └─ main
└─dist
└─ main
└─ main.exe
動作を確認するため、生成された dist/main/main.exe を実行します。起動すると、コンソール画面が表示され、以下の文字が出力されます。
パッケージ化された Python アプリケーションが動作することが確認できました。
ビルドオプション
単一の実行ファイルにパッケージする
パッケージ方法には、One-Folder モード (デフォルト) と One-File モードがあります。 One-Folder モードは、関連するファイルを1つのディレクトリにパッケージ化します。一方、One-File モードは単一の実行ファイルにパッケージ化します。
One-File モードは、必要なファイルをすべて単一の実行ファイルにまとめることができるメリットがありますが、実行時に一時ディレクトリに関連ファイルを展開するため、One-Folder モードより起動に少し時間がかかります。
One-File モードでパッケージするには、–onefile オプションを指定します。
pyinstaller main.py --onefile
コンソール画面を非表示にする
デフォルトでは、実行時にコンソールが表示されます。バックグラウンドで動作させたい場合は、-w オプションを指定します。
pyinstaller main.py -w
データを同梱する
画像やテキストなど Python アプリケーションで使用するデータをパッケージに同梱できます。
–add-data オプションで <同梱するファイルのパス>;<展開先のディレクトリパス> という形式で指定します。同梱するファイルは複数指定可能です。
展開先のディレクトリのパスの基点は、One-Folder モードでは パッケージされたディレクトリ、One-File モードでは 実行時に展開された一時ディレクトリになります。
例: ./sample.txt を <展開先のディレクトリ>/sample.txt に同梱する。
One-Folder モードの場合
pyinstaller .\main.py --add-data ".\sample.txt;.\"
def main():
with open("sample.txt") as f:
print(f.read())
input("Press to any key to exit.") # 終了させないため
if __name__ == "__main__":
main()
One-File モードの場合
One-File モードでは、実行時に展開された一時ディレクトリにそのファイルが配置されるため、参照するには sys._MEIPASS でそのパスを取得する必要があります。
pyinstaller .\main.py --add-data ".\sample.txt;.\" --onefile
import sys
from pathlib import Path
def base_dir():
if hasattr(sys, "_MEIPASS"):
return Path(sys._MEIPASS) # 実行ファイルで起動した場合
else:
return Path(".") # python コマンドで起動した場合
def main():
with open(base_dir() / "sample.txt") as f:
print(f.read())
input("Press to any key to exit.") # 終了させないため
if __name__ == "__main__":
main()
ディレクトリも同梱できます。
- data ディレクトリを <展開先のディレクトリ>/data に同梱する。
pyinstaller .\main.py --add-data "data;data"
ワイルドケースも使用できます。
- data ディレクトリ内の *.png ファイルを<展開先のディレクトリ> に同梱する。
pyinstaller .\main.py --add-data "*.png;."
ビルド設定のファイルを作成する
ビルド時の設定を行うには、これまで紹介してきたコマンドライン引数で指定する方法と、次に紹介する .spec ファイルに記載する方法があります。
ビルドの設定をファイルで残せるため、.spec ファイルに記載する方法がおすすめです。
.spec ファイルは pyi-makespec コマンドに pyinstaller を実行する際のオプションを指定して実行することで、その設定が反映された .spec ファイルを作成できます。
pyi-makespec [pyinstaller を実行する際のオプション] main.py
中身は Python なので手動で編集も可能です。作成した .spec ファイルを pyinstaller の実行時に指定することで、この設定を適用してビルドを行えます。
pyinstaller .\main.spec
実行ファイルのサイズ
作成されたパッケージは Python インタプリタ及び依存するライブラリが同梱されるため、ファイルサイズが大きくなります。Python アプリケーション内で import しているライブラリは同梱されてしまうため、import するライブラリは必要最小限にしましょう。 以下、Windows 環境でいくつかのライブラリを同梱した際のファイルサイズを検証しました。標準ライブラリのみであれば、10 MB 未満に収まりましたが、numpy 及びそれを使用する OpenCV や pandas といったライブラリを使用する場合、データサイズが肥大化する傾向がありました。下記に私の環境でパッケージ化した際のファイルサイズを参考値として記載します。
- 標準ライブラリのみ: 6.4MB
- numpy: 19.8MB
- numpy + pandas: 43.4MB
- OpenCV: 44.9 MB
まとめ
今回は Pyinstaller を使用して Python アプリケーションから実行ファイルを作成する方法について解説しました。作成したアプリケーションを Python の動作環境がない PC でも動かすことができるようになるため、アプリケーションを配布する際に活用するとよいでしょう。