PyInstaller 可以用來把 Python 程式打包起來,方便在其他機器上執行,省去安裝 Python 以及所使用套件的時間。
安裝 PyInstaller:
pip install pyinstall
說明:可能會裝不起來,前面可能需要加 sudo, 改用 sudo pip install pyinstall
PyInstaller 詳細使用方法:
https://pyinstaller.readthedocs.io/en/stable/usage.html
PyInstaller 進階使用方法:
https://pythonhosted.org/PyInstaller/advanced-topics.html#the-toc-and-tree-classes
PyInstaller打包用指令:
pyinstaller myscript.py
或是用
pyinstaller myscript.spec --clean
這個 .spec 檔案會在第1次執行 pyinstall myscript.py 之後產生
喜歡產生單一檔案的人,可以使用下面這行來 build
pyinstaller -F myscript.spec --clean
pyinstall default 是 -D,Create a one-folder bundle containing an executable (default).
在 Linux 執行之後產生的檔案:
由於沒有加參數,跑出來的結果和使用 py2exe 跑出來一樣,打包程式無法知道程式會去使用那些外部檔案,所以必需要調整 .spec 檔案,打包完成之後,完全看不到 pyd 或 py 檔案,全部變成執行檔。
參數調整的方法是:
pyinstaller, 也會自動產生一個 .spec 檔案。
可以加 -F 參數:
-F, –onefile
Create a one-file bundled executable.
Spec 修改的官方文件:
https://pyinstaller.readthedocs.io/en/stable/spec-files.html
附註1:加進去的 datas 居然是要改成用程式去讀出來。 @_@;
Using Data Files from a Module
If the data files you are adding are contained within a Python module, you can retrieve them using pkgutils.get_data()
.
For example, suppose that part of your application is a module named helpmod
. In the same folder as your script and its spec file you have this folder arrangement:
helpmod
__init__.py
helpmod.py
help_data.txt
Because your script includes the statement import helpmod
, PyInstaller will create this folder arrangement in your bundled app. However, it will only include the .py
files. The data file help_data.txt
will not be automatically included. To cause it to be included also, you would add a datas
tuple to the spec file:
a = Analysis(...
datas= [ ('helpmod/help_data.txt', 'helpmod' ) ],
...
)
When your script executes, you could find help_data.txt
by using its base folder path, as described in the previous section. However, this data file is part of a module, so you can also retrieve its contents using the standard library function pkgutil.get_data()
:
import pkgutil
help_bin = pkgutil.get_data( 'helpmod', 'help_data.txt' )
In Python 3, this returns the contents of the help_data.txt
file as a binary string. If it is actually characters, you must decode it:
help_utf = help_bin.decode('UTF-8', 'ignore')
附註2:Hidden Import
If your app (or libries you depend on) doing dynamic import, such as using __import__
function, pyinstaller would not be able to detect that in it’s static analysis and the module would be missing in the final executable. To help pyinstaller discover these modules, it provide hook mechanism but I failed to get it work. Passing the module name through command line options did work however:-
pyinstallers --onefile -p /path/to/mylib --hidden-import=awscli.converters script.py
For a few hidden import, above is fine but as the number grow, passing it as command line option quickly getting out of hand. The hook mechanism provide utility function that can discover all sub-modules.
Pyinstaller setting icon
pyinstaller.exe --onefile --windowed --icon=app.ico app.py
使用 –icon 可以在 windows 裡產生相對應的 icon 也加在 .spec 裡 exe 的 block:
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='settings',
debug=False,
strip=False,
upx=True,
console=True,
icon='your_icon.ico' )