使用PyInstaller 打包Python项目是一个常见的需求,它可以将Python程序及其所有依赖项打包成一个独立的可执行文件或者安装文件,方便在没有安装Python环境的机器上运行。本随笔介绍WxPython跨平台开辟框架中使用PyInstaller 进行打包处理惩罚,包括在WIndow平台下天生独立的exe文件,松散结构的exe文件和目录,以及在MacOS上天生安装包的处理惩罚过程。
1. 安装和使用 PyInstaller 进行程序打包处理惩罚
PyInstaller是现在最流行的Python打包工具之一。它可以将Python脚本打包成独立的可执行文件,支持Windows、Linux和macOS平台。
打包后的可执行文件可以在没有 Python 环境的机器上运行。PyInstaller 会主动分析程序的依赖关系,并将所有必要的库和资源打包到一个文件或者一个文件夹中。
cx_Freeze是另一个常用的Python打包工具,同样支持跨平台。
Py2exe是专门用于将Python脚本打包成Windows平台可执行文件的工具。
首先,确保您的Python环境已经安装。然后,通过pip安装PyInstaller。在VSCode或者其他编辑器的下令行(终端)中执行以下下令:在项目目录下,使用PyInstaller下令来打包您的Python脚本。假设您的主程序文件名为main.py,则可以使用以下下令:- pyinstaller --onefile main.py
复制代码 这里的--onefile选项指示PyInstaller天生一个单独的可执行文件,而不是一个包含多个文件的文件夹。PyInstaller还支持许多其他选项,如--icon来指定应用程序的图标,--windowed或--noconsole来避免在Windows上打开下令行窗口等。
PyInstaller完成打包后,会在dist目录下天生可执行文件(或文件夹,如果您没有使用--onefile选项)。进入dist目录,您应该能看到一个名为main(或您指定的名称,如果使用了--name选项)的可执行文件。
如果统统正常,您的Python程序现在应该会在没有Python环境的环境下运行。
使用PyInstaller打包Python项目是一个简单而强盛的方法,可以让您的程序更加便携和易于分发。通过遵循上述步调,您可以轻松地将您的Python项目打包成一个可执行文件。
常用选项
PyInstaller 提供了很多下令行选项,用于定制打包过程。以下是一些常用的选项:
--onefile
天生单个可执行文件。默认环境下,PyInstaller 会天生一个文件夹,里面包含了可执行文件和所有相关的依赖项。如果你希望打包成一个独立的可执行文件(大概会更大),可以使用 --onefile 选项。
--noconsole
如果你正在创建一个 GUI 应用程序(如使用 wxPython 或 PyQt),而且不希望显示控制台窗口,可以使用 --noconsole 选项。此选项会隐藏控制台窗口,适用于 Windows 和 macOS。
--icon
为天生的可执行文件指定一个图标。图标文件可以是 .ico(Windows)或 .icns(macOS)格式。
--onedir
天生一个包含可执行文件和所有依赖项的文件夹,而不是单个文件。你可以将整个文件夹分发给其他用户。
build 文件夹被PyInstaller用来收集和准备捆绑的文件,它包含分析的结果和一些额外的日志。在大多数环境下,你可以忽略这个文件夹的内容,除非你想调试题目。
dist (代表 "分发")文件夹包含要分发的文件。这包括你的应用程序,捆绑成一个可执行文件,以及任何相关的库(比方WxPython、PyQt6 等)和二进制.so 文件。
2、使用.spec文件进行定制打包处理惩罚
打包过程中,PyInstaller 会天生一个 .spec 文件。这个文件包含了 PyInstaller 的设置信息,此中包含了构建过程的所有设置信息。你可以修改这个文件来定制打包过程。
如果我们执行下面代码或者指定更多的参数的代码- pyinstaller --onefile --icon=your_icon.ico main.py
复制代码 PyInstaller 都会天生一个 .spec 文件,然后可以编辑 main.spec 文件,比方:- # main.spec
- # -*- mode: python ; coding: utf-8 -*-
- block_cipher = None
- a = Analysis(['main.py'],
- pathex=['/path/to/your/script'], # 项目的路径
- binaries=[],
- datas=[('data/*.txt', 'data')], # 资源文件
- hiddenimports=['some_module'], # 隐藏导入模块
- hookspath=[],
- runtime_hooks=[],
- excludes=[],
- win_no_prefer_redirects=False,
- win_private_assemblies=False)
- pyz = PYZ(a.pure)
- exe = EXE(pyz,
- a.scripts,
- a.binaries,
- a.zipfiles,
- a.datas,
- name='main',
- debug=False,
- strip=False,
- upx=True,
- console=False) # 设置是否显示控制台
复制代码 一般环境下,我们的.spec文件会比这个更多的内容,固然原则上.spec文件支持跨平台的设置,不外我们在实际中往往根据不同的平台设置特定的.spec文件。
你可以手动修改 .spec 文件来添加资源文件、修改导入模块、定制输出路径等。
你可以通过编辑.spec 文件,在EXE、COLLECT和BUNDLE块下添加一个name= ,为PyInstaller提供一个更好的名字,以便为应用程序(和dist 文件夹)使用。
EXE下的名字是可执行文件的名字,BUNDLE下的名字是应用程序包的名字。
修改完成后,执行以下下令来重新打包:
解决常见题目
- 缺少依赖库:如果打包后运行时出现缺少模块的错误,可以尝试将缺少的模块加入到 hiddenimports 中,或者通过 --hidden-import 选项指定:
- 大文件:如果使用 --onefile 时打包后的文件太大,思量使用 --onedir 或通过压缩文件等方法进行优化。
- 处理惩罚资源文件:如果你的应用程序包含非 Python 代码的资源(如图像、设置文件、数据文件等),你需要通过 --add-data 选项指定资源文件的路径,或者在 .spec 文件中修改 datas 选项。
- 动态链接库,如果你的应用程序依赖于特定的动态链接库(如 DLL 文件或 .so 文件),你需要将这些库包含到打包中。可以在 .spec 文件的 binaries 选项中指定:
- 多平台支持:PyInstaller 支持 Windows、Linux 和 macOS 等多个平台,但需要在相应的平台上打包。比方,如果你要为 Windows 用户创建可执行文件,最好在 Windows 上运行 PyInstaller 来天生 Windows 的 .exe 文件。如果在 macOS 上打包,天生的文件只能在 macOS 上运行。
PyInstaller 有丰富的文档,提供了详细的使用说明和常见题目解答,你可以通过以下链接访问:
这些文档和资源能资助你深入了解 PyInstaller 的使用方式,并解决在打包过程中大概遇到的题目。
3、WxPython跨平台开辟框架中定制不同平台的 .spec文件
前面介绍了,我们推荐使用修改设置.spec文件的方式天生打包文件,而且可以通过定制不同平台的.spec文件,以便实现更好的处理惩罚,避免冲突。
对于不同平台的图标处理惩罚,我们可以使用代码来判断,.spec文件自己可以编写python的代码的。- import sys
- import os
- from pathlib import Path
- if sys.platform == "win32":
- icon = "app/images/app.ico"
- elif sys.platform == "darwin":
- icon = "app/images/app.icns"
复制代码 另外我们的业务窗体是动态根据路径解析的,因此在打包的时候,会遗漏的,为了解决这个题目,需要手动把视图部分的模块加载到hidden-import集合中,如下所示。
为了避免手工填写出错和麻烦,使用python函数递归处理惩罚目录的视图模块。- def collect_modules(directory):
- modules = []
- for root, dirs, files in os.walk(directory):
- for file in files:
- if file.endswith(".py") and file != "__init__.py": # 排除 __init__.py 文件
- module_path = os.path.relpath(os.path.join(root, file), directory)
- module_name = module_path.replace(os.path.sep, ".").replace(".py", "")
- modules.append(module_name)
- return modules
- # 使用动态加载目录下的模块方式
- hiddenimports = collect_modules("app/views")
- hiddenimports = [f"views.{module}" for module in hiddenimports]
复制代码 这样在修改里面的变量即可。- # Analysis: PyInstaller Analysis object
- a = Analysis(
- ["app/main.py"],
- pathex=[],
- binaries=[],
- datas=[
- ("app/images/splash.png", "images"),
- ("app/.env", "."),
- ("app/settings.ini", "."),
- ],
- hiddenimports=hiddenimports,
- hookspath=[],
- hooksconfig={},
- runtime_hooks=[],
- excludes=[],
- noarchive=False,
- optimize=0,
- )
复制代码 1)WIndows平台的打包文件天生
然后指定EXE(用于Window的处理惩罚打包)
[code]# PYZ: PyInstaller PYZ objectpyz = PYZ(a.pure)# EXE: PyInstaller EXE objectexe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name="wxpython_project", debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, # True启用/False禁用下令行窗口 onefile=False, # |