You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller能否仅打包Python二进制,首次运行时通过pip装依赖减包体积?

延迟依赖安装以缩小Python应用分发体积

问题背景

使用PyInstaller打包基于pywebview、TensorFlow构建的Python应用时,生成的可执行文件体积远超预期,原因是PyInstaller默认会打包所有依赖库。希望实现仅打包Python二进制核心文件,在应用首次运行时通过pip install自动安装所需依赖,以此缩小分发包体积。

此前尝试通过直接调用pip模块实现延迟安装,代码如下:

import sys, io
buffer = io.StringIO()
sys.stdout = sys.stderr = buffer

import pip
pip.main(['install', 'numpy'])

import webview
webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
webview.start()

但运行打包后的demo.exe时出现错误:

Traceback (most recent call last):
  File "demo.py", line 7, in <module>
  File "pip\__init__.py", line 13, in main
  File "pip\_internal\utils\entrypoints.py", line 43, in _wrapper
  File "pip\_internal\cli\main.py", line 68, in main
  File "pip\_internal\commands\__init__.py", line 114, in create_command
  File "importlib\__init__.py", line 127, in import_module
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'pip._internal.commands.install'

错误原因

  1. pip.main()是已废弃的旧API,pip官方不推荐在代码中直接调用内部模块
  2. PyInstaller默认不会打包pip的内部命令模块,导致运行时找不到pip._internal.commands.install

解决方案

一、修复PyInstaller打包时的延迟安装逻辑

放弃直接调用pip内部API,改用subprocess调用系统级pip,这种方式更稳定且无需额外打包pip内部模块:

import subprocess
import sys

# 调用当前环境的pip安装指定依赖,可添加版本号确保兼容性
subprocess.check_call(
    [sys.executable, "-m", "pip", "install", "numpy==1.26.0", "pywebview==4.0.0", "tensorflow==2.15.0"],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

import webview
webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
webview.start()

打包时只需确保不包含目标依赖,可通过--exclude-module参数明确排除:

pyinstaller --onefile --exclude-module=numpy --exclude-module=pywebview --exclude-module=tensorflow demo.py

二、PyInstaller轻量化打包优化

如果想进一步缩小基础包体积,可结合以下参数:

  • --clean:清理打包缓存
  • --noconsole:针对GUI应用,隐藏命令行窗口
  • --strip:剥离二进制文件中的调试信息(仅适用于类Unix系统)

三、替代打包工具

1. cx_Freeze

配置仅打包Python解释器和业务代码,排除所有大依赖,在代码中处理延迟安装:
编写setup.py配置文件:

import sys
from cx_Freeze import setup, Executable

# 针对Windows GUI应用设置base
base = 'Win32GUI' if sys.platform == 'win32' else None

executables = [Executable('demo.py', base=base)]

setup(
    name='LightweightApp',
    version='1.0',
    description='App with delayed dependency installation',
    executables=executables,
    options={
        'build_exe': {
            'excludes': ['numpy', 'pywebview', 'tensorflow'],
            'optimize': 2  # 优化字节码
        }
    }
)

执行打包命令:

python setup.py build

2. PyOxidizer

支持构建最小化Python运行时,可配置首次启动时自动从PyPI下载安装依赖。核心配置示例(pyoxidizer.toml):

[project]
name = "myapp"
version = "0.1.0"

[[python_packaging.pip_install]]
packages = ["numpy==1.26.0", "pywebview==4.0.0", "tensorflow==2.15.0"]
install_mode = "after_launch"  # 延迟安装到启动后

[[python_packaging.entry_point]]
type = "console_script"
name = "myapp"
module = "demo"
function = "main"

执行打包:

pyoxidizer build

3. Nuitka

将Python代码编译为C语言二进制,可通过参数排除依赖,实现延迟安装:
打包命令:

nuitka --standalone --nofollow-imports=numpy,pywebview,tensorflow --windows-disable-console demo.py

代码中同样使用subprocess调用pip安装依赖。

注意事项

  • 首次运行需确保设备联网,建议在应用启动时添加联网提示
  • 指定依赖版本可避免不同环境下的兼容性问题
  • 延迟安装会增加首次启动时间,需在用户体验和包体积之间做平衡

内容的提问来源于stack exchange,提问作者link89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:47:12