Pyinstallerでpythonをexe化すると、pythonがインストールされていないPCでも作ったpythonのプログラムを利用することができます。
今回は、スクリプトで外部のファイルを参照している場合のexe化についてです。
本体でのパスの指定とexe化時のオプション設定
コード内でcsvファイルやtxtファイルを参照しているものをpyinstallerでexe化する際に–onefileのオプションをつければ、1つのファイルにまとめることができます。
スクリプトで参照しているファイルを一緒に同梱せずに実行ファイル化すると、参照しているファイルが見つからないというエラーが発生します。
本体のコードでのフォルダの指定とexe化時の参照ファイルの同梱のオプションが必要です。
本体コードでのフォルダの指定
まずは、本体コードの中でのフォルダの指定を工夫しておきます。
if getattr(sys, 'frozen', False):
# 実行ファイルからの実行時
script_dir = sys._MEIPASS
else:
# スクリプトからの実行時
script_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(script_dir, "sample.csv")
ifで分岐させた3行目の「実行ファイルからの実行時」のsys._MEIPASS がonefileとした場合の実行時の一時フォルダです。
elseのほうは通常のフォルダの指定で、コードを書いているときはこちらでパスを指定します。
exe化時のファイルの同梱のオプション
ファイルのexe化の時に、–onefileのほかに「–add -data “sample.csv;.”」というオプションを足します。
>pyinstaller --onefile --add-data "sample.csv;." --add-data "sample.txt;." main.py
ファイルが複数の場合は、–add-data を複数回書いてファイルを追加できます。
上記以外に、人に配るなら、–noconsoleも入れておいたほうがいいでしょう。
pyinstallerのオプションでは以下を使っています。
- –onefile:ファイルを一つにまとめる。
- –noconsole:実行時にコンソールを表示させない
- –add-data:参照するファイルを実行ファイルに同梱する。同じ階層のファイルなら
–add-data “sample.csv;.” など - –exclude:不要なライブラリなどを指定して同梱の対象外とする
- –clean:前回exe化した際に作成されたファイルを削除してからexe化する
同梱しない場合のパスの指定
同梱しない場合はコードで以下のpathにすれば、exeファイルと同じフォルダを指定できます。
exeファイルの場所を変えればそれに対応してexe_pathも変わるので、exeファイルと同じフォルダに参照file用のフォルダを置いて使うこともできます。
随時更新するようなファイル、ゲームでいうとセーブデータのようなファイルはexeファイルに取り込んでも更新できないのでこのようなパスの指定で外出しして対応できます。
exe_path = os.path.dirname(os.path.abspath(sys.argv[0]))
–add-data と–add-binary
ファイルを追加するのに、–add-data と–add-binaryという2つのオプションがあります。
正確な理解ではないかも知れませんが、
–add-data は、ファイルをそのまま同梱する。
–add-binary は、pyinstallerで処理してexeに織り込む。
ということのようです。
add-binaryは、何らかの理由でimportされないライブラリやドライバを追加するときに使うものです。
Pythonがない環境で実行できるようにするのにpythonのライブラリなどがそのまま動くわけないのでpyinstallerで処理してもらわないと動かないですもんね。
一方で、画像ファイルやCSVファイルなどはそのまま処理の対象にするだけのものなので、処理せずそのまま同梱していいので、–add-data でいいようです。画像ファイルは形式はバイナリなのでadd-binaryというわけではないようです。
処理せず参照するだけの画像ファイルなどはバイナリ形式のファイルでも–add-dataでいいようです。
実験はしてませんが、–add-dataでいいものを–add-binaryとしても動くと思われますが、逆に–add-binaryとすべきものを–add-dataとすると動かないということだと思います。
【広告】
コメント