python打包之一文打尽:pyinstaller 和 nuitka 打包参数与使用方法详解

应用程序开发完毕,一般都需要对程序进行打包后发布,除开源项目外,很少有发布源码的。另一方面,Python 程序的运行必须要有 Python 的环境,如果每次都给客户电脑上部署一个python运行环境,就显得啰嗦又复杂,这时我们就要将 Python 程序打包为 exe 文件。这样,在 Windows 平台下,就可以直接运行该程序,不论有没有 Python 环境。

python程序的打包模块也比较多,但常用的有两种,pyinstaller和nuitka,掌握这两个打包模块,一般的项目打包就能够应付了。本文仅对这两种打包模块的常用命令进行介绍,供程序打包时做参考。

一、pyinstaller

最终因此拿出一节来记录一下我这两天的历程。我只能说没有解决不了的问题只有定义不清晰的问题,只要方向对了,问题会随着了解的加深而迎刃而解。

(一)安装pyinstaller

在终端安装,,相对比较简单:

pip install pyinstaller

注意,如果没有打开虚拟环境,此时的安装位置在全局环境中,使用的时候要注意。

(二)一般打包方法

1.打包命令形式

在你想放置应用的文件夹下打开cmd,pyinstaller + 参数 +文件入口或打包定义文档

python打包之一文打尽:pyinstaller 和 nuitka 打包参数与使用方法详解_第1张图片

注意观察上面的目录结构和命令形式。

2. 打包参数

(1)通用参数
参数名 描述 说明
-h 显示帮助
-v 显示版本号
–distpath 生成文件放在哪里 默认:当前目录的dist文件夹内
–workpath 生成过程中的中间文件放在哪里 默认:当前目录的build文件夹内
-y 如果dist文件夹内已经存在生成文件,则不询问用户,直接覆盖 默认:询问是否覆盖
–upx-dir UPX_DIR 指定upx工具的目录 默认:execution path
-a 不包含unicode支持 默认:尽可能支持unicode
–clean 在本次编译开始时,清空上一次编译生成的各种文件 默认:不清除
–log-level LEVEL 控制编译时pyi打印的信息 一共有6个等级,由低到高分别为TRACE DEBUG INFO(默认) WARN ERROR CRITICAL。也就是默认清空下,不打印TRACE和DEBUG信息
(2)与生成结果有关的参数
参数名 描述 说明
-D 生成one-folder的程序(默认) 生成结果是一个目录,各种第三方依赖、资源和exe同时存储在该目录
-F 生成one-file的程序 生成结果是一个exe文件,所有的第三方依赖、资源和代码均被打包进该exe内
–specpath 指定.spec文件的存储路径 默认:当前目录
-n 生成的.exe文件和.spec的文件名 默认:用户脚本的名称,即main.py和main.spec
(3)指定打包哪些资源、代码
参数名 描述 说明
–add-data 打包额外资源 用法:pyinstaller main.py --add-data=src;dest。windows以;分割,linux以:分割
–add-binary 打包额外的代码 用法:同–add-data。与–add-data不同的是,用binary添加的文件,pyi会分析它引用的文件并把它们一同添加进来
-p 指定额外的import路径,类似于使用PYTHONPATH 参见PYTHONPATH
–hidden-import 打包额外py库 pyi在分析过程中,有些import没有正确分析出来,运行时会报import error,这时可以使用该参数
–additional-hooks-dir 指定用户的hook目录 hook用法参见其他,系统hook在PyInstaller\hooks目录下
–runtime-hook 指定用户runtime-hook 如果设置了此参数,则runtime-hook会在运行main.py之前被运行
–exclude-module 需要排除的module pyi会分析出很多相互关联的库,但是某些库对用户来说是没用的,可以用这个参数排除这些库,有助于减少生成文件的大小
–key pyi会存储字节码,指定加密字节码的key 16位的字符串

–add-binary 使用实例可以参考:《python3 pyinstaller 打包后执行文件运行错误 No such file or directory 和 Cannot load native module 解决方法》python3 pyinstaller 打包后执行文件运行错误 No such file or directory 和 Cannot load native module 解决方法_whatday的博客-CSDN博客

(4)生成参数
参数名 描述 说明
-d 执行生成的main.exe时,会输出pyi的一些log,有助于查错 默认:不输出pyi的log
-s 优化符号表 原文明确表示不建议在windows上使用
–noupx 强制不使用upx 默认:尽可能使用。
(5)其他
参数名 描述 说明
–runtime-tmpdir 指定运行时的临时目录 默认:使用系统临时目录
(6)Windows和Mac特有的参数
参数名 描述 说明
-c 显示命令行窗口 与-w相反,默认含有此参数
-w 不显示命令行窗口 编写GUI程序时使用此参数有用。
-i 为main.exe指定图标 pyinstaller -i beauty.ico main.py
(7)Windows特有的参数
参数名 描述 说明
–version-file 添加版本信息文件 pyinstaller --version-file ver.txt
-m, --manifest 添加manifest文件 pyinstaller -m main.manifest
-r RESOURCE 请参考原文
–uac-admin 请参考原文
–uac-uiaccess 请参考原文

常用参数有以下几个:
-F:仅仅生成一个文件,不暴露其他信息,启动较慢。
-D:生成一个文件夹,里面是多文件模式,启动快。
-w:窗口模式打包,不显示控制台。
-c:跟图标路径,作为应用icon。

3.打包示例

(1)一般打包
pyinstaller -F 文件名.py

此时双击生成的程序,会出来一个CMD控制台,如果程序有输出,会在控制台上输出相应的程序运转过程。

(2)打包pyqt5文件
pyinstaller --paths PyQt5模块路径 -D -w --icon=窗口图标文件 文件名.py
# 参数说明:
# --paths:指定第三方模块的安装路径。
# -w:表示窗口程序。
# --icon:可选项,如果设置了窗口图标,则指定相应文件路径;如果没有,则省略。
# 文件名.py:窗口程序的入口文件。

此时打包生成一个带依赖资源文件夹的程序,不显示控制台窗口,并装软件图标打入程序。

二、Nuitka

Nuitka是一个Python代码打包工具,它可以将Python代码转换成C或C++代码,并最终生成一个可执行文件。

 官方参考网站

Nuitka the Python Compiler — Nuitka the Python Compiler documentation

Nuitka的目标是创建一个功能齐全的Python解释器的C语言对应版本,这样就可以将Python代码编译成可执行文件,同时也可以实现Python的动态类型特性。

使用Nuitka可以有效地提高Python代码的运行效率,因为它将Python代码转换成C或C++代码,并使用高效的编译器将其编译成二进制代码。此外,Nuitka还提供了很多优化选项,可以进一步改善代码的效率。

(一)安装nuitka

pip install nuitka

(二)一般打包方法

1. 最简单的方法:

nuitka 程序文件.py

使用这条命令生成的exe可以正常运行。

但如果将生成的exe拷贝到其他路径执行,将会执行失败,提示找不到mdl模块,这是因为使用上述命令生成的exe里面是并不包含上面的mdl模块,于是在执行该exe的时候,它会尝试去调用mdl.py,如果找不到mdl.py,当然就会提示找不到模块,这和py文件的执行原理是一样的。

exe同级目录下面会有一个python3x.dll文件,执行exe文件时,如果需要调用外部模块,需要这个文件的支持。

关于python3x.dll
python3x.dll是与版本相对应的,如果是python3.8.3,那么就是python38.dll。实际上,这个文件和python安装目录下面的python3x.dll是同一个文件(的拷贝)。python3x.dll相当于一个运行时(runtime),类似于javac,或者微软的framwork,python代码通过nuitka生成了二进制代码(exe或者pyd),但仍然通过python3x.dll保留了python的特性,比如调用一个python模块

现在将整个目录拷贝到其他路径,可以发现exe能够正常执行,因为此时exe文件能够通过python3x.dll找到mdl.py。

如果不想借助python3x.dll去调用模块,就要将这个模块打包进exe

nuitka --follow-import-to=mdl hello.py

再次将生成的exe单独拷贝到其他地方执行,可以看到能够正常运行,此时不再需要拷贝python3x.dll和其他任何的文件。

2.打包tk-inter开发的GUI程序

nuitka --standalone --onefile --enable-plugin=tk-inter --remove-output --windows-disable-console  xxx.py

参数说明:
--standalone     独立环境,使结果可移植
--onefile    打包为单个exe文件
--enable-plugin=tk-inter    打包tkinter模块的需要
--remove-output    打包结束后删除产生的临时文件
--windows-disable-console    去掉运行时cmd窗口

此处注意和上面用pyinstall打包pyqt5的打包方法对比。

3.复杂一点的打包命令解析

nuitka --standalone --mingw64 --show-memory --show-progress --nofollow-imports --enable-plugin=pyqt5 --follow-import-to=need --output-dir=output 你的.py


# 参数说明:
# --standalone     独立环境,使结果可移植
# --mingw64        指定c/c++编译器
# --show-memory    显示内存的占用
# --show-progress  显示编译的进度
# --nofollow-imports  所有的import不编译,交给python3x.dll执行
# --enable-plugin=pyqt5   打包pyqt5模块的需要
# --follow-import-to=need  need为你需要编译成C/C++的py文件夹命名
# --output-dir=output     输出文件目录
# --onefile               打包为单个exe文件

注意:刚开始调试的时候, --windows-disable-console这个命令一定不要加入,否则看不到报错

(三)常用参数速查

--standalone 独立环境,使结果可移植
--windows-disable-console 去掉CMD控制窗口
--output-dir=out 生成exe到out文件夹下面去
--show-progress 显示编译的进度
--show-memory 显示内存的占用
--enable-plugin=pyside6  打包pyside6模块的需要
--plugin-enable=tk-inter 打包tkinter模块的需要
--plugin-enable=numpy 打包numpy,pandas,matplotlib模块的需要
--plugin-enable=torch 打包pytorch的需要
--plugin-enable=tensorflow 打包tensorflow的需要
--windows-icon-from-ico=你的.ico 软件的图标
--windows-company-name=Windows下软件公司信息
--windows-product-name=Windows下软件名称
--windows-file-version=Windows下软件的信息
--windows-product-version=Windows下软件的产品信息
--windows-file-description=Windows下软件的作用描述
--windows-uac-admin=Windows下用户可以使用管理员权限来安装
--linux-onefile-icon=Linux下的图标位置
--onefile 打包为单个exe文件
--include-package=复制比如numpy,PyQt5 这些带文件夹的叫包或者轮子
--include-module=复制比如when.py 这些以.py结尾的叫模块
–-include-package-data=包含给定软件包名称中的数据文件,等号后软件包名称。有的时候Nuitka并不能正确分析出一些Python软件包所需要使用的数据文件,在运行程序时提示FileNotFoundError等错误,此时就需要使用该选项。如:--include-package-data=ultralytics
–-include-data-files= 按文件名包含数据文件,等号后的格式为。SRC指的是文件夹的路径,DEST指的是文件夹相对于打包结果的路径,其中DEST只能使用相对路径。如:--include-data-files=/Users/admin/Downloads/yolov5n.pt=./yolov5n.pt
-–include-data-dir= 包含文件夹中的数据文件,等号后的格式为。使用方法与--include-data-files=相同。
--follow-import-to=MODULE/PACKAGE    如果使用该模块,请遵循该模块;如果是一个包,请遵循整个包。可以多次给定。默认为空。

(四)nuitka打包优缺点

1.Nuitka优点:

程序运行速度较快。

相对于pyinstaller,打包之后的程序占用空间较小。

2.Nuitka缺点:

打包时间比较长,新手非常容易出错。

(五)注意事项

1. 首先下载并安装c/c++编译器

推荐使用https://download.csdn.net/download/qq_58168857/88152647?spm=1001.2014.3001.5503,经过本人多个项目验证,此编译器能解决您的大部分涉及c/c++ 软件包的安装、编译调用出错问题。

2 .关于参数--mingw64

实际上 --mingw64--msvc=MSVC是一对孪生参数,这两个参数二选一,用于指定编译器,如果当前环境既安装了mingw64,又安装了msvc,可以使用该参数选择兼容性最好的编译器,建议使用mingw64。如果不存在上面两种编译器都存在的情况,就不需要显式设置这个参数,默认会调用系统中能用的编译器。

3.关于直接用C语言开发的python包的打包

  •  Numpy等类似c程式和pyd的调用还是忽略编译好,有大佬测试,编译后反而使打包出来的程序运行更慢。
  • PyQT,Numpy,Scipy,Pandas,Opencv,OpenpyXL等pyd的模块不编译,交给python3x.dll来调用,避免模块依赖失败。生成的UI_xxx.py文件和你编写的py模块(可以包含IP,密码)放到一个下一级的文件夹,设置为必须编译为C/C++。从此你的打包成功率提升到95%,exe打开速度提升到一秒左右


4.参数plugin control

这部分参数用于设置对某些第三方库或者python功能进行支持,在使用--standalone时才会用到

(1)如果程序中使用了pyqt或者pyside,那么  --plugin-enable = qt-plugins

(2)如果程序中使用了numpy, scipy, pandas, matplotlib,那么 --plugin-enable=numpy

如果使用了这些库或功能,但是忘了进行插件参数设置,命令运行过程中会以红字今天提醒,按照提醒对命令进行调整即可

(3)如果有多个插件需要启用 --plugin-enable=numpy   --plugin-enable=qt-plugins  --plugin-enable=tensorflow

可以使用 nuitka --plugin-list查看可用的插件
 

三、附件:nuitka参数列表

Usage: __main__.py [--module] [--run] [options] main_module.py

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  --module              Create an extension module executable instead of a
                        program. Defaults to off.
  --standalone          Enable standalone mode in build. This allows you to
                        transfer the created binary to other machines without
                        it relying on an existing Python installation. It
                        implies these option: "--recurse-all". You may also
                        want to use "--python-flag=no_site" to avoid the
                        "site.py" module, which can save a lot of code
                        dependencies. Defaults to off.
  --python-arch=PYTHON_ARCH
                        Architecture of Python to use. One of "x86" or
                        "x86_64". Defaults to what you run Nuitka with
                        (currently "x86_64").
  --python-debug        Use debug version or not. Default uses what you are
                        using to run Nuitka, most likely a non-debug version.
  --python-flag=PYTHON_FLAGS
                        Python flags to use. Default uses what you are using
                        to run Nuitka, this enforces a specific mode. These
                        are options that also exist to standard Python
                        executable. Currently supported: "-S" (alias
                        "nosite"), "static_hashes" (do not use hash
                        randomization), "no_warnings" (do not give Python
                        runtime warnings), "-O" (alias "noasserts"). Default
                        empty.
  --python-for-scons=PYTHON_SCONS
                        If using Python3.3 or Python3.4, provide the path of a
                        Python binary to use for Scons. Otherwise Nuitka can
                        use what you run Nuitka with or a "scons" binary that
                        is found in PATH, or a Python installation from
                        Windows registry.
  --warn-implicit-exceptions
                        Enable warnings for implicit exceptions detected at
                        compile time.
  --warn-unusual-code   Enable warnings for unusual code detected at compile
                        time.
  --assume-yes-for-downloads
                        Allow Nuitka to download code if necessary, e.g.
                        dependency walker on Windows.

  Control the inclusion of modules and packages:
    --include-package=PACKAGE
                        Include a whole package. Give as a Python namespace,
                        e.g. ``some_package.sub_package`` and Nuitka will then
                        find it and include it and all the modules found below
                        that disk location in the binary or extension module
                        it creates, and make it available for import by the
                        code. Default empty.
    --include-module=MODULE
                        Include a single module. Give as a Python namespace,
                        e.g. ``some_package.some_module`` and Nuitka will then
                        find it and include it in the binary or extension
                        module it creates, and make it available for import by
                        the code. Default empty.
    --include-plugin-directory=MODULE/PACKAGE
                        Include the content of that directory, no matter if
                        it's used by the given main program in a visible form.
                        Overrides all other recursion options. Can be given
                        multiple times. Default empty.
    --include-plugin-files=PATTERN
                        Include into files matching the PATTERN. Overrides all
                        recursion other options. Can be given multiple times.
                        Default empty.

  Control the recursion into imported modules:
    --follow-stdlib, --recurse-stdlib
                        Also descend into imported modules from standard
                        library. This will increase the compilation time by a
                        lot. Defaults to off.
    --nofollow-imports, --recurse-none
                        When --recurse-none is used, do not descend into any
                        imported modules at all, overrides all other recursion
                        options. Defaults to off.
    --follow-imports, --recurse-all
                        When --recurse-all is used, attempt to descend into
                        all imported modules. Defaults to off.
    --follow-import-to=MODULE/PACKAGE, --recurse-to=MODULE/PACKAGE
                        Recurse to that module, or if a package, to the whole
                        package. Can be given multiple times. Default empty.
    --nofollow-import-to=MODULE/PACKAGE, --recurse-not-to=MODULE/PACKAGE
                        Do not recurse to that module name, or if a package
                        name, to the whole package in any case, overrides all
                        other options. Can be given multiple times. Default
                        empty.

  Immediate execution after compilation:
    --run               Execute immediately the created binary (or import the
                        compiled module). Defaults to off.
    --debugger, --gdb   Execute inside "gdb" to automatically get a stack
                        trace. Defaults to off.
    --execute-with-pythonpath
                        When immediately executing the created binary
                        (--execute), don't reset PYTHONPATH. When all modules
                        are successfully included, you ought to not need
                        PYTHONPATH anymore.

  Dump options for internal tree:
    --xml               Dump the final result of optimization as XML, then
                        exit.

  Code generation choices:
    --full-compat       Enforce absolute compatibility with CPython. Do not
                        even allow minor deviations from CPython behavior,
                        e.g. not having better tracebacks or exception
                        messages which are not really incompatible, but only
                        different. This is intended for tests only and should
                        not be used for normal use.
    --file-reference-choice=FILE_REFERENCE_MODE
                        Select what value "__file__" is going to be. With
                        "runtime" (default for standalone binary mode and
                        module mode), the created binaries and modules, use
                        the location of themselves to deduct the value of
                        "__file__". Included packages pretend to be in
                        directories below that location. This allows you to
                        include data files in deployments. If you merely seek
                        acceleration, it's better for you to use the
                        "original" value, where the source files location will
                        be used. With "frozen" a notation "" is used. For compatibility reasons, the
                        "__file__" value will always have ".py" suffix
                        independent of what it really is.

  Output choices:
    -o FILENAME         Specify how the executable should be named. For
                        extension modules there is no choice, also not for
                        standalone mode and using it will be an error. This
                        may include path information that needs to exist
                        though. Defaults to  on this platform.
                        .exe
    --output-dir=DIRECTORY
                        Specify where intermediate and final output files
                        should be put. The DIRECTORY will be populated with C
                        files, object files, etc. Defaults to current
                        directory.
    --remove-output     Removes the build directory after producing the module
                        or exe file. Defaults to off.
    --no-pyi-file       Do not create a ".pyi" file for extension modules
                        created by Nuitka. This is used to detect implicit
                        imports. Defaults to off.

  Debug features:
    --debug             Executing all self checks possible to find errors in
                        Nuitka, do not use for production. Defaults to off.
    --unstripped        Keep debug info in the resulting object file for
                        better debugger interaction. Defaults to off.
    --profile           Enable vmprof based profiling of time spent. Not
                        working currently. Defaults to off.
    --graph             Create graph of optimization process. Defaults to off.
    --trace-execution   Traced execution output, output the line of code
                        before executing it. Defaults to off.
    --recompile-c-only  This is not incremental compilation, but for Nuitka
                        development only. Takes existing files and simply
                        compile them as C again. Allows compiling edited C
                        files for quick debugging changes to the generated
                        source, e.g. to see if code is passed by, values
                        output, etc, Defaults to off. Depends on compiling
                        Python source to determine which files it should look
                        at.
    --generate-c-only   Generate only C source code, and do not compile it to
                        binary or module. This is for debugging and code
                        coverage analysis that doesn't waste CPU. Defaults to
                        off. Do not think you can use this directly.
    --experimental=EXPERIMENTAL
                        Use features declared as 'experimental'. May have no
                        effect if no experimental features are present in the
                        code. Uses secret tags (check source) per experimented
                        feature.
    --disable-dll-dependency-cache
                        Disable the dependency walker cache. Will result in
                        much longer times to create the distribution folder,
                        but might be used in case the cache is suspect to
                        cause errors.
    --force-dll-dependency-cache-update
                        For an update of the dependency walker cache. Will
                        result in much longer times to create the distribution
                        folder, but might be used in case the cache is suspect
                        to cause errors or known to need an update.

  Backend C compiler choice:
    --clang             Enforce the use of clang. On Windows this requires a
                        working Visual Studio version to piggy back. Defaults
                        to off.
    --mingw64           Enforce the use of MinGW64 on Windows. Defaults to
                        off.
    --msvc=MSVC         Enforce the use of specific MSVC version on Windows.
                        Allowed values are e.g. 14.0, specify an illegal value
                        for a list of installed compilers.  Defaults to the
                        most recent version.
    -j N, --jobs=N      Specify the allowed number of parallel C compiler
                        jobs. Defaults to the system CPU count.
    --lto               Use link time optimizations if available and usable
                        (gcc 4.6 and higher). Defaults to off.

  Tracing features:
    --show-scons        Operate Scons in non-quiet mode, showing the executed
                        commands. Defaults to off.
    --show-progress     Provide progress information and statistics. Defaults
                        to off.
    --show-memory       Provide memory information and statistics. Defaults to
                        off.
    --show-modules      Provide a final summary on included modules. Defaults
                        to off.
    --verbose           Output details of actions taken, esp. in
                        optimizations. Can become a lot. Defaults to off.

  Windows specific controls:
    --windows-dependency-tool=DEPENDENCY_TOOL
                        When compiling for Windows, use this dependency tool.
                        Defaults to depends.exe, other allowed value is
                        'pefile'.
    --windows-disable-console
                        When compiling for Windows, disable the console
                        window. Defaults to off.
    --windows-icon=ICON_PATH
                        Add executable icon (Windows only).

  Plugin control:
    --plugin-enable=PLUGINS_ENABLED, --enable-plugin=PLUGINS_ENABLED
                        Enabled plugins. Must be plug-in names. Use --plugin-
                        list to query the full list and exit. Default empty.
    --plugin-disable=PLUGINS_DISABLED, --disable-plugin=PLUGINS_DISABLED
                        Disabled plugins. Must be plug-in names. Use --plugin-
                        list to query the full list and exit. Default empty.
    --plugin-no-detection
                        Plugins can detect if they might be used, and the you
                        can disable the warning via --plugin-disable=plugin-
                        that-warned, or you can use this option to disable the
                        mechanism entirely, which also speeds up compilation
                        slightly of course as this detection code is run in
                        vain once you are certain of which plug-ins to use.
                        Defaults to off.
    --plugin-list       Show list of all available plugins and exit. Defaults
                        to off.
    --user-plugin=USER_PLUGINS
                        The file name of user plugin. Can be given multiple
                        times. Default empty.

 

你可能感兴趣的:(应用技巧,踩坑经验,python中高级编程技巧,python,经验分享,pyqt)