很多时候我们用python编写了一些程序或者工具之后,可能需要在其他电脑上运行它,或者与不会编程的人分享。这时候我们就需要用到可以把python打包成可执行文件的工具,例如:Pyinstaller、Py2app、cx_Freeze等。在这里,我将分享一些我们在使用这些工具进行打包过程中遇到的一些问题和解决方法。
PyInstaller将Python应用程序及其所有依赖项打包成一个单独的包。用户可以在不安装Python解释器或任何模块的情况下运行打包的应用程序。PyInstaller支持Python 3.7及更新版本,并正确打包了许多主要的Python包,如numpy、matplotlib、PyQt、wxPython等。
PyInstaller已在Windows、MacOS X和Linux上进行了测试。然而,它不是一个交叉编译器;如果要制作Windows应用程序,则在Windows上运行PyInstaller;如果要制作Linux应用程序,则在Linux上运行PyInstaller,依此类推。
详细信息可以见官方说明。
如果安装了pip可以使用如下命令安装Pyinstaler
pip install -U pyinstaller
可以执行命令pyinstaller -v
检查安装的版本,有输出对应的版本号即为安装成功:
可以使用如下命令打包python文件:
pyinstaller -F -w myapp.py
常用的参数说明如下:
更多详细参数可以在终端执行pyinstaller -h
查看:
打包的过程很顺利,但是发现执行不起来,于是把打包参数中的参数-w去掉了,直接用pyintaleer -F myapp.py
打包,然后查看执行的过程:
可以看到报错是NO module named 'mutagen'
,但是直接执行python文件是正常的。
于是重新进行打包,仔细看了打包的过程发现了问题,打包过程中使用的pyinstaller和python的版本都不对。原来是因为我的电脑安装了两个不同版本的python,旧版本的python也安装了Pyinstaller,执行的过程中用了旧的Pyinstaller进行了打包,但是由于那个环境没有安装mutagen库,导致打包的时候失败了。
解决方案: 直接切换到旧版本的python把Pyinstaller卸载了,再在新的python重新安装了Pyinstaller,重新打包执行成功。
所以如果存在多版本的环境,一定要检查清楚当前使用的版本!!!
py2app 是一个 Python setuptools 命令,它允许您从 Python 脚本制作独立的 Mac OS X 应用程序包和插件。
py2app 在目的和设计上与 Windows 的 py2exe 相似。
注意:py2app 必须在 macOS 上使用才能构建应用程序,它不能在其他平台上创建 Mac 应用程序。详细信息见官方。
可以使用如下命令安装py2app:
pip install py2app
第一步是为您的脚本创建一个setup.py文件。setup.py 是“项目文件”,它告诉setuptools构建应用程序所需的一切信息。我们将使用py2applet命令来做到这一点:
py2applet --make-setup MyApp.py
可以执行vi setup.py
编辑setup.py文件配置icon文件、需要打包的文件、需要打包的模块等,如下是一个示例:
from setuptools import setup
APP = ['main.py'] # 需要打包的Python程序
DATA_FILES = [] # 需要打包的其他文件,如图片、配置文件等
OPTIONS = { # 打包选项
'iconfile': 'icon.icns', # 应用程序图标
'plist': {'CFBundleShortVersionString': '0.1.0'}, # 应用程序版本号
'packages': ['wx', 'numpy'], # 需要打包的Python模块
'includes': ['sip', 'PyQt4'], # 需要包含的其他模块
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
以上参数说明如下:
APP:需要打包的Python程序,可以是单个文件或多个文件组成的列表。
DATA_FILES:需要打包的其他文件,如图片、配置文件等,可以是单个文件或多个文件组成的列表。
OPTIONS:打包选项,是一个字典,用来配置应用程序的图标、版本号、需要打包的Python模块、需要包含的其他模块等。
iconfile:应用程序图标文件的路径,可以是.icns、.iconset或.png格式的文件。
plist:应用程序的属性列表,包含了应用程序的基本信息,如名称、版本号等。
packages:需要打包的Python模块,可以是单个模块或多个模块组成的列表。
includes:需要包含的其他模块,可以是单个模块或多个模块组成的列表。
setup():用来描述打包的过程,其中包含了以下参数:
app:需要打包的Python程序,与APP参数相同。
data_files:需要打包的其他文件,与DATA_FILES参数相同。
options:打包选项,是一个字典,用来配置应用程序的各种属性,与OPTIONS参数相同。
setup_requires:用来指定需要安装的Python模块,即py2app模块。
更多详细的参数说明,可以参考py2app官方文档。
可以执行如下命令使用py2app生成.app文件:
python setup.py py2app
执行成功后就可以在当前路径下的dist文件夹找到对应的.app文件了。
打包的.app文件默认在app下的 Contents/Resources/ 路径下执行程序,如果需要生成日志文件、读取当前路径下的文件需要注意文件路径的配置。
cx_Freeze从 Python 脚本创建独立的可执行文件,具有相同的性能,是跨平台的,理论上可以在Python 本身可以运行的任何平台上运行。cx_Freeze的当前版本是 6.14,它支持 Python 3.7 到 3.11。详细说明见官方文档。
可以执行如下命令安装cx_Freeze
pip install cx_Freeze
创建一个setup.py文件,文件内容大致如下:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {
"excludes": ["tkinter", "unittest"],
"zip_include_packages": ["encodings", "PySide6"],
}
# base="Win32GUI" should be used only for Windows GUI app
base = "Win32GUI" if sys.platform == "win32" else None
setup(
name="guifoo",
version="0.1",
description="My GUI application!",
options={"build_exe": build_exe_options},
executables=[Executable("guifoo.py", base=base)],
)
上述setup.py
文件中的各个参数说明如下:
name
:程序的名称。
version
:程序的版本号。
author
:程序的作者。
description
:程序的描述信息。
options
:打包选项,其中build_exe
选项指定了构建exe程序所需的相关信息。
includes
:需要包含的模块列表。include_files
:需要打包的其他文件和数据。packages
:需要打包的Python包列表。excludes
:需要排除的模块列表。executables
:包含所有要构建的exe程序的列表。每个exe程序都需要指定以下信息:
script
:要打包的Python脚本。base
:构建exe程序的基础平台。在本例中,我们将base
设置为None
,这意味着在MAC环境下使用默认的GUI界面;如果要在Windows环境下使用GUI界面,则需要将base
设置为"Win32GUI"
。icon
:exe程序的图标文件路径。在本例中,我们将其设置为None
,这意味着不使用图标文件。可以执行如下命令打包生成可执行文件,windows和MAC的有细微区别:
python setup.py bdist_msi # 打包windows的exe包
python setup.py bdist_mac # 打包MAC的app包