Pythonスクリプトから実行ファイルを作る方法

Pythonスクリプトから実行ファイルを作る方法

概要

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-Folder モードの構成例
One-Folder モードの構成例

One-File モードは、必要なファイルをすべて単一の実行ファイルにまとめることができるメリットがありますが、実行時に一時ディレクトリに関連ファイルを展開するため、One-Folder モードより起動に少し時間がかかります。

One-File モードの構成例
One-File モードの構成例

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 でも動かすことができるようになるため、アプリケーションを配布する際に活用するとよいでしょう。