py2exeを使って、pythonのスクリプトをexeファイルにしましょう。
いくつかハマりポイントがあって大変だったのでまとめてみます。
複数のハマリポイントではまった理由を追記しました(2017/03/13)
Python バージョン: 2.7.10
pyexe バージョン: 0.6.9
pythonスクリプトを書く
今回はこんなかんじの、
ファイルを作るだけの簡単なスクリプトをexeにしようと思います。
create_file.py
with open('test.txt', 'w') as f: f.write('Hello, world!')
py2exeをインストール
トップページの上のメニューに有るダウンロードページからpy2exeをダウンロード。
ハマりポイント1
インストール自体は簡単。
ただ64bitマシンなのに、64bitのほうじゃ動かなくて、32bitの方にしたら動いた。
ハマりポイント2
pip install py2exeでは、python3向けのpy2exeしかインストールできないので注意。
exeを作るためのsetup.pyを書く
py2exeではexeファイルを作るための設定を書いてあげないといけない。
作ったpythonスクリプトと同じ階層にsetup.pyというファイルを作る。
. ├── create_file.py └── setup.py
中身はこんな感じで。
from distutils.core import setup import py2exe option = { 'bundle_files':1, 'compressed': True } setup( options = {'py2exe': option}, console=['create_file.py'], zipfile = 'create_file.zip', )
option
bundle_files: いくつのファイルするか。1にしておけばいい。
compressed: Trueにするとバイナリサイズが減るらしい
setupの引数
console: 目的のファイル。ここをconsoleではなくてwindowにすると、実行時にコンソールが立ち上がらないらしい。
zipfile = 生成されるzipファイルの名前。指定しないとlibrary.zipになる。
exeファイルをつくつ
setup.pyも書いたことだし、exeファイルをつくろう。
以下を実行する。
python setup.py py2exe
そうすると、dist/というフォルダが出来て、その中のexeファイルができている。
├── build │ └── bdist.win32 ├── create_file.py ├── dist │ ├── create_file.exe <- これがメインのexeファイル │ ├── create_file.zip │ └── w9xpopen.exe └── setup.py
create_file.exeをダブルクリックすると無事test.txtができた。
やったー。
これでPython環境のはいってないWindowsユーザにもPythonツールがばらまけるぞ!
ハマりポイント3
コマンドプロンプトでは実行できるんだけど、py2exeを認識してくれなくてcygwinでは実行できなかった。cygwinで使うにはパスをどこかに追加してあげなきゃいけないのかなーと思うんだけど、もう調べる気力がないのでだれか教えてください。
追記(2017/03/13)
WindowsのPythonにpy2exeをインストールしたのだから、cygwinから実行するPythonをWindowsのPythonにしない限り使えないのは当然という感じ。CygwinからWindowsのPython使うとパス関係等色々問題が起きるので、cmdではWindowsのPython、CygwinではCygwinでインストールしたPython使おう。
py2exeはコマンドプロンプトで使おう。
ちなみに、windows歴1ヶ月の私は、exeファイルは何でもはいってるスペシャル実行ファイルだと思って、「できました!」って先輩にexeファイルだけを渡したのだけど、
distディレクトリ以下をまとめて渡さないと動かせないです。残念。
実体は.zipの中に入っているのですね・・・。
参考
こっちを見た方がいろいろわかる
[Python] pyInstallerの遅さにがっかりしてpy2exeにしたら爆速で驚いた件 – Nobwak's Lair
さいごに
ハマりポイントは、py2exeの、というよりもWindowsのハマりポイントでしたね・・・・。
Mac歴21年のWindows超初心者にはWindowsいろいろわからなすぎる(´・ω・`)(´・ω・`)
追記(2017/03/13)
__file__を使おうとすると、py2exeのexe化したときに失敗します。
代わりにsys.argv[0]を使うようにしましょう。
root_dir = os.path.dirname(os.path.abspath(__file__))
のように現在のディレクトリを定義するのに使うことが多いかと思いますが、
その場合はこんな感じで解決してます。
root_dir = os.path.dirname(os.path.abspath(sys.argv[0]))