首页
关于
Search
1
python打包-Nuitka快速上手
106 阅读
2
python打包-pystand快速上手
23 阅读
3
python打包-pyinstaller快速上手
18 阅读
4
开始我的python学习之路
17 阅读
5
python学习记录第25天
10 阅读
默认分类
登录
Search
Typecho
累计撰写
29
篇文章
累计收到
32
条评论
首页
栏目
默认分类
页面
关于
搜索到
29
篇与
的结果
2023-06-07
python打包-pystand快速上手
每个 Python 程序员可能都会遇到这样的场景:你写了一个 Python 程序,可能是一个简单的、包含单个文件的 、只使用了标准库的 Python 脚本,抑或是一个庞大的、包含多个模块的、甚至引用了大量的第三方库的复杂 Python 应用,如何将他们送到目标用户手中,让他们能很顺利地使用起来呢?一种方案就是写一个详尽的文档,连带着你的程序一起发送给用户。文档中要说明,目标用户如何在自己机器上安装 Python 环境及依赖的包,如何对程序进行配置,等等。但倘若你的目标用户没用过 Python 甚至不懂编程,此种方案执行起来便困难重重。另一种方案,就是将 Python 程序“打包”成可执行程序(.exe),只要目标用户具备基本的电脑操作技能,便能很容易地将程序运行起来。在 Windows 平台上,将 Python 程序“打包”为可执行程序(.exe)的方案很多,我尝试过的方案有如下几种:cx_Freezepy2exePyInstallerNuitkaPyStandpynsist本文将讲解如何使用 PyStand 打包你的 Python 程序。PyStand 是由国内编程大神韦易笑开发的。作者本人在知乎上对 PyStand 的用法进行了详尽的介绍。推荐读者在阅读接下来的内容前先阅读一下知乎上这个问答:怎么样打包 pyqt 应用才是最佳方案?或者说 pyqt 怎样的发布方式最优?一个简单的例子:Hello PyStand我们先来看一个简单的用 PyStand 打包的 Python 程序的目录结构:其中:runtime 目录:存放嵌入式(embeddable)Python 解释器;site-packages 目录:存放依赖的第三方包;PyStand.exe:可执行程序,供目标用户使用;PyStand.int:初始化脚本(启动代码),由 PyStand.exe 调用;这里的 PyStand.int 实际上是一个普通的 Python 脚本,它的后缀也可以是 .py 或 .pyw。.py 后缀大家都很熟悉。如果你写的 Python 脚本是一个图形用户界面(GUI)程序,将后缀由 .py 改为 .pyw 后,程序启动时就不会再弹出一个黑色的命令行窗口。下面来看一个简单的打包示例。假设我们有一个 Python 脚本 HelloPyStand.py:# coding: utf-8 import ctypes MB_OK = 0x0 ICON_INFO = 0x40 ctypes.windll.user32.MessageBoxW( None, 'Hello, PyStand!', 'A simple PyStand sample:', MB_OK | ICON_INFO) # References: # [Python MessageBox with Icons using ctypes and windll](https://stackoverflow.com/questions/27257018/python-messagebox-with-icons-using-ctypes-and-windll)这个程序很简单:使用 Win32 API MessageBoxW 弹出一个消息提示框。从 PyStand 的 Releases 页面下载一个预编译版本的 PyStand。以最新版的 PyStand v1.0.6 为例,作者提供了如下四个预编译版本:PyStand-py37.7z:PyStand 32 位 GUI 程序,搭配的是 Python 3.7 的 32 位嵌入式包。PyStand-py38.7z:PyStand 32 位 GUI 程序,搭配的是 Python 3.8 的 32 位嵌入式包。PyStand-py38-pyqt5.7z:PyStand 32 位 GUI 程序预,搭配的是 Python 3.8 的 32 位嵌入式包。此外,site-packages 中还包含了一个经过简单裁剪的 PyQt5。PyStand-py38-pyqt5-lite.7z:PyStand 32 位 GUI 程序预编译版,搭配的是 Python 3.8 的 32 位嵌入式包。此外,site-packages 中还包含了一个经过大幅裁剪的 PyQt5 包。如果你的程序不依赖于 PyQt5,下载前两个版本即可。前两个版本搭载的 Python 版本分别是 3.7 和 3.8。如果你需要更新版本的 Python,可自行去 Python 官网下载相应版本的 embeddable Python 即可。我们的 HelloPyStand.py 不依赖于 PyQt5,因此下载前两个版本任一即可。我这里选择 PyStand-py38.7z。下载后,解压,用文本编辑器打开 PyStand.int,用 HelloPyStand.py 中的代码替换掉原来的内容,然后双击 PyStand.exe。如果你看到了如下界面,那么恭喜你,你成功了!当然,你也可以不要 PyStand.int,直接将你的 HelloPyStand.py 复制到解压后 PyStand.exe 所在的目录下,然后将 PyStand.exe 重命名为 HelloPyStand.exe,双击,也可以运行。一个复杂的例子:ViTables刚刚的例子有些简单,以至于成功来得太突然!下面,我们看一个复杂的例子。去年,我接触了一个 HDF5 文件查看器 ViTables。它是用 PyQt 开发的。最初,我尝试在 Anaconda 里安装它,结果失败(https://github.com/uvemas/ViTables/issues/79 )。后来,有了 PyStand 后,我又做了一次尝试。对于像 ViTables 这样的依赖第三方库的 Python 程序,能否成功地安装所有其依赖的第三方库,是成败的关键。我们可以考虑从 PyStand-py38-pyqt5.7z 作为起点来打包 ViTables,但这里为了让读者对用 PyStand 打包的流程有更深入的了解,我们还使用刚刚上面的那个演示里用到的不包含 PyQt5 包的预编译版作为起点。第一步:安装 pip,有了 pip 才能安装其它第三方包。StackOverflow 上有个问题:pip with embedded python,按照高票答案操作即可。先用文本编辑器打开 runtime 目录下的 python38._pth,我们可以看到如下内容:python38.zip . # Uncomment to run site.main() automatically #import site取消注释最后一行代码:python38.zip . # Uncomment to run site.main() automatically import site然后,去 get-pip-py 下载 get-pip.py,并将其放置在 runtime 目录下。打开命令行窗口,cd 到 runtime 目录下,然后用 runtime 目录下的 python.exe 执行 get-pip.py:.\python.exe get-pip.py安装成功后,我们便可以进行下一步。第二步:下载 ViTables 最新版本代码,并安装其依赖的包。ViTables 没有依赖的 git 子模块,因此我们从其仓库主页通过浏览器下载其最新版本的源码压缩包即可。下载完成后,将其解压,并放置在与 runtime、site-packages 同级的目录下:ViTables 依赖的第三方库记录在 ViTables\requirements.txt 这个文件里。打开命令行窗口,cd 到 runtime 目录下,然后用 runtime 目录下的 python.exe 安装 ViTables 依赖的第三方包:.\python.exe -m pip install -r ..\ViTables\requirements.txt这样,安装的包就会放置在 runtime\Lib\site-packages 下。在 PyStand 中,site-packages 要和 runtime 在同一个目录下。因此,将 runtime\Lib 目录下 site-packages 这个文件夹挪至 runtime 的外面。第三步:尝试运行 ViTables。经过前两步,我们已成功地安装了 ViTables 及其全部依赖,是时候运行一下了。我们首先把 PyStand.exe 重命名为 ViTables.exe,然后,将 PyStand.int 重命名为 ViTables.int。ViTables.int 中的内容如下:# coding: utf-8 from ViTables.vitables.start import gui gui()运行 ViTables.exe。咦!不对!过了半天也没弹出任何窗体。是时候进行故障排查了。PyStand.exe 虽是个 GUI 应用,却用 freopen 对 stdout、stderr 进行了重定向。只要从命令行或 PowerShell 中运行它,错误信息便会打印出来:原来是找不到模块。ViTables 源码目录如下:而主程序源码实际上全部在 vitables 子目录下(见图中红框所示)。因此,为确保 ViTables 各模块正确加载,我们需要将 ViTables 添加到 sys.path 下。修改我们的 ViTables.int 如下:# coding: utf-8 import sys sys.path.append(r'.\ViTables') from vitables.start import gui gui()再次运行,成功!第四步:清理。最后一步是清理不必要的文件,以减小打包后的文件体积。就拿 ViTables 来说,我们可以只保留 ViTables\vitables 这个子目录,doc、examples、macoxapp、mswindows、tests 等目录以及其他文件都可以不要。裁剪完 ViTables 后,我们发现我们实际上可以不必要多级目录。因此,先将 ViTables 重命名为 ViTables-old。然后将 ViTables-old 下的 vitables 剪切到上一级目录,使它和 ViTables-old 在同一目录,然后删除 ViTables-old 即可。我们的 ViTables.int 就可以简化为:# coding: utf-8 from vitables.start import gui gui()清理完 ViTables 中的无用文件后,接下来就是清理第三方包中的多余文件。这一步需要你对你所使用的库有一些基础的了解,哪些可以删,哪些不能删,要做到心里有数。裁剪 PyQt 的话,具体可以参考韦易笑大神在知乎上的回答。当然,在裁剪过程中也记得多备份,如果某一步删错了文件,还可以回退重来。PyStand 定制如果 PyStand Releases 页面提供的预编译版本无法满足我们的使用要求,我们也可以自己编译 PyStand。目前,PyStand Releases 页面只提供了 32 位 GUI 版的 PyStand,如果你想要一个命令行版的 PyStand(比如:你要打包的 Python 脚本是命令行应用,而非 GUI 应用),或是 64 位的 PyStand(比如:你想使用 64 位的 Python),亦或是你想更改 PyStand 的图标(比如:ViTables 就有自己的图标),均需要自己去编译 PyStand。要从源码编译 PyStand,你需要先在电脑上安装:C++ 编译器CMakeC++ 编译器可以选择微软的 MSVC 或是 GCC。其中,MSVC 可以通过在电脑上安装 Visual Studio 获得。Visual Studio 分很多版本:社区版、专业版、企业版等。对于 PyStand,Visual Studio Community(社区版)就够用了。安装的时候记得勾选 C++ 编程语言支持。我在 VS2010、VS2017、VS2019、VS2022 中均成功编译过 PyStand。GCC 则可以通过安装 MinGW/MinGW-w64/TDM-GCC 获得,也可以通过安装 CLion/CodeBlocks/CodeLite/Qt 等集成开发环境来获得。无论是 MSVC 还是 MinGW,为了便于开发人员从命令行调用它们,它们一般上都提供了一个命令提示符开发环境。在这个开发环境里,PATH 环境变量、头文件路径、库文件路径均已设置停当,用户可以直接在命令行里调用编译器、链接器等工具。如果安装了 Visual Studio,我们一般上可以在开始菜单程序列表里找到名为 Developer Command Prompt(翻译为:开发人员命令提示符)的快捷方式。PyStand 使用 CMake 作为其构建系统,要想自己编译,需要在电脑上安装 CMake,并要求你掌握 CMake 的基本用法。CMake 可以作为命令行工具来调用。此外,CMake 一般上还提供了一个 GUI 工具(在 Windows 上,这个 GUI 版的一般叫:cmake-gui.exe)。CMake GUI 版对新手可能够友好一些,你可以通过搜索引擎搜索 CMake GUI 的基本用法。接下来,我主要讲一下 CMake 命令行工具的基本用法。这要求你安装 CMake 后将 CMake 可执行文件的路径添加到 Windows 系统的 PATH 环境变量里。大部分命令行工具会提供一个 -h/--help 参数(或者两者皆有),用于查看该命令行工具的帮助信息。在我的机器上,执行:cmake --help后的输出如下:Usage cmake [options] <path-to-source> cmake [options] <path-to-existing-build> cmake [options] -S <path-to-source> -B <path-to-build> Specify a source directory to (re-)generate a build system for it in the current working directory. Specify an existing build directory to re-generate its build system. Options -S <path-to-source> = Explicitly specify a source directory. -B <path-to-build> = Explicitly specify a build directory. -C <initial-cache> = Pre-load a script to populate the cache. -D <var>[:<type>]=<value> = Create or update a cmake cache entry. -U <globbing_expr> = Remove matching entries from CMake cache. -G <generator-name> = Specify a build system generator. -T <toolset-name> = Specify toolset name if supported by generator. -A <platform-name> = Specify platform name if supported by generator. --toolchain <file> = Specify toolchain file [CMAKE_TOOLCHAIN_FILE]. --install-prefix <directory> = Specify install directory [CMAKE_INSTALL_PREFIX]. -Wdev = Enable developer warnings. -Wno-dev = Suppress developer warnings. -Werror=dev = Make developer warnings errors. -Wno-error=dev = Make developer warnings not errors. -Wdeprecated = Enable deprecation warnings. -Wno-deprecated = Suppress deprecation warnings. -Werror=deprecated = Make deprecated macro and function warnings errors. -Wno-error=deprecated = Make deprecated macro and function warnings not errors. --preset <preset>,--preset=<preset> = Specify a configure preset. --list-presets = List available presets. -E = CMake command mode. -L[A][H] = List non-advanced cached variables. --build <dir> = Build a CMake-generated project binary tree. --install <dir> = Install a CMake-generated project binary tree. --open <dir> = Open generated project in the associated application. -N = View mode only. -P <file> = Process script mode. --find-package = Legacy pkg-config like mode. Do not use. --graphviz=[file] = Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for more. --system-information [file] = Dump information about this system. --log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE> = Set the verbosity of messages from CMake files. --loglevel is also accepted for backward compatibility reasons. --log-context = Prepend log messages with context, if given --debug-trycompile = Do not delete the try_compile build tree. Only useful on one try_compile at a time. --debug-output = Put cmake in a debug mode. --debug-find = Put cmake find in a debug mode. --trace = Put cmake in trace mode. --trace-expand = Put cmake in trace mode with variable expansion. --trace-format=<human|json-v1> = Set the output format of the trace. --trace-source=<file> = Trace only this CMake file/module. Multiple options allowed. --trace-redirect=<file> = Redirect trace output to a file instead of stderr. --warn-uninitialized = Warn about uninitialized values. --no-warn-unused-cli = Don't warn about command line options. --check-system-vars = Find problems with variable usage in system files. --profiling-format=<fmt> = Output data for profiling CMake scripts. Supported formats: google-trace --profiling-output=<file> = Select an output path for the profiling data enabled through --profiling-format. --help,-help,-usage,-h,-H,/? = Print usage information and exit. --version,-version,/V [<f>] = Print version number and exit. --help-full [<f>] = Print all help manuals and exit. --help-manual <man> [<f>] = Print one help manual and exit. --help-manual-list [<f>] = List help manuals available and exit. --help-command <cmd> [<f>] = Print help for one command and exit. --help-command-list [<f>] = List commands with help available and exit. --help-commands [<f>] = Print cmake-commands manual and exit. --help-module <mod> [<f>] = Print help for one module and exit. --help-module-list [<f>] = List modules with help available and exit. --help-modules [<f>] = Print cmake-modules manual and exit. --help-policy <cmp> [<f>] = Print help for one policy and exit. --help-policy-list [<f>] = List policies with help available and exit. --help-policies [<f>] = Print cmake-policies manual and exit. --help-property <prop> [<f>] = Print help for one property and exit. --help-property-list [<f>] = List properties with help available and exit. --help-properties [<f>] = Print cmake-properties manual and exit. --help-variable var [<f>] = Print help for one variable and exit. --help-variable-list [<f>] = List variables with help available and exit. --help-variables [<f>] = Print cmake-variables manual and exit. Generators The following generators are available on this platform (* marks default): * Visual Studio 17 2022 = Generates Visual Studio 2022 project files. Use -A option to specify architecture. Visual Studio 16 2019 = Generates Visual Studio 2019 project files. Use -A option to specify architecture. Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files. Optional [arch] can be "Win64" or "ARM". Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files. Optional [arch] can be "Win64" or "ARM". Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files. Optional [arch] can be "Win64" or "ARM". Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files. Optional [arch] can be "Win64" or "ARM". Visual Studio 10 2010 [arch] = Deprecated. Generates Visual Studio 2010 project files. Optional [arch] can be "Win64" or "IA64". Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files. Optional [arch] can be "Win64" or "IA64". Borland Makefiles = Generates Borland makefiles. NMake Makefiles = Generates NMake makefiles. NMake Makefiles JOM = Generates JOM makefiles. MSYS Makefiles = Generates MSYS makefiles. MinGW Makefiles = Generates a make file for use with mingw32-make. Green Hills MULTI = Generates Green Hills MULTI files (experimental, work-in-progress). Unix Makefiles = Generates standard UNIX makefiles. Ninja = Generates build.ninja files. Ninja Multi-Config = Generates build-<Config>.ninja files. Watcom WMake = Generates Watcom WMake makefiles. CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files. CodeBlocks - NMake Makefiles = Generates CodeBlocks project files. CodeBlocks - NMake Makefiles JOM = Generates CodeBlocks project files. CodeBlocks - Ninja = Generates CodeBlocks project files. CodeBlocks - Unix Makefiles = Generates CodeBlocks project files. CodeLite - MinGW Makefiles = Generates CodeLite project files. CodeLite - NMake Makefiles = Generates CodeLite project files. CodeLite - Ninja = Generates CodeLite project files. CodeLite - Unix Makefiles = Generates CodeLite project files. Eclipse CDT4 - NMake Makefiles = Generates Eclipse CDT 4.0 project files. Eclipse CDT4 - MinGW Makefiles = Generates Eclipse CDT 4.0 project files. Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files. Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files. Kate - MinGW Makefiles = Generates Kate project files. Kate - NMake Makefiles = Generates Kate project files. Kate - Ninja = Generates Kate project files. Kate - Unix Makefiles = Generates Kate project files. Sublime Text 2 - MinGW Makefiles = Generates Sublime Text 2 project files. Sublime Text 2 - NMake Makefiles = Generates Sublime Text 2 project files. Sublime Text 2 - Ninja = Generates Sublime Text 2 project files. Sublime Text 2 - Unix Makefiles = Generates Sublime Text 2 project files.我们接下来会讲到这些参数:-S-B-G-A-D--build--config--target使用 CMake 构建工具的 C、C++ 项目源码根目录里一般上包含一个名为 CMakeLists.txt 的 CMake 脚本。CMake 工具也主要围绕该脚本来工作。使用 CMake 构建一个项目一般上分为三步(假设 CMakeLists.txt 是现成的):接:配置(Configure)化:生成(Generate)发:构建(Build)在配置阶段,用户可以指定:生成器(Generator)的类型(通过 -G 参数指定)要生成的库的位数(32 位、64 位)(通过 -A 参数指定)库的类型(静态库、动态库)(通过 -D 参数指定)库的安装路径(通过 -D 或 --install-prefix 参数指定)CMake options(通过 -D 参数指定)额外的宏定义(通过 -D 参数指定)额外的头文件/库文件查找路径等(通过 -D 参数指定)在配置阶段,需要将包含 CMakeLists.txt 的源码路径作为一个参数传给 CMake。如果项目中包含多个模块目录,且每个模块都有自己的 CMakeLists.txt,则需要指定最顶层的 CMakeLists.txt 所在路径。指定 CMakeLists.txt 需要用到 -S 参数。例如:cmake -S ..习惯上,人们会省去 -S,直接写:cmake ..使用 CMake 构建项目的过程中会生成大量临时文件。为了避免这些临时文件“污染”源码,以及方便后续清理,人们推荐使用“out of source build”。所谓“out of source build”就是建立一个独立于源码的路径,作为构建目录,用于存储 CMake 构建过程中产生的临时文件。可以通过 -B 参数指定生成目录。例如:cmake .. -B .如果想用当前路径作为生成路径,则可省略 -B 参数。以 PyStand 为例,你可以从如下几种实践中选择其一:实践一:# 克隆源代码到本地 git clone https://github.com/skywind3000/PyStand # 建立一个与 PyStand 源码目录同级的目录用于存储构建过程中的临时文件 mkdir PyStand-build # cd 至 build 目录 cd PyStand-build # 指定源码的相对路径,开始 Configure # 等价于: # cmake -S ../PyStand -B . cmake ../PyStand # 开始 Build cmake --build . --config Release实践二:# 克隆源代码到本地 git clone https://github.com/skywind3000/PyStand # cd 到 PyStand 源码的根目录(CMakeLists.txt 所在目录) cd PyStand # 在 PyStand 目录下创建一个 build 子目录,用于存储构建过程中生成的临时文件 mkdir build # cd 到 build 目录,你也可以用 pushd build(构建完成后 popd build) cd build # 指定源码的相对路径,开始 Configure # 等价于: # cmake -S .. -B . cmake .. # 开始 Build cmake --build . --config Release实践三:# 克隆源代码到本地 git clone https://github.com/skywind3000/PyStand # cd 到 PyStand 源码的根目录(CMakeLists.txt 所在目录) cd PyStand # 在 PyStand 目录下创建一个 build 子目录,用于存储构建过程中生成的临时文件 mkdir build # 当前路径依然在 PyStand 根目录,但我们通过 -B 参数指定了构建目录 # 等价于: # cmake -S . -B build cmake -B build # 开始 Build cmake --build build --config Release我个人更习惯使用第二或第三种方案。CMake 每个版本所支持的 Generator 都会有所区别,具体可通过 --help 参数查阅帮助信息。以上面我的机器上执行 cmake --help 的输出为例,自 Generators 开始的内容便是我安装的 CMake 所支持的生成器的列表。从这个列表中可以看出,该版本的 CMake 支持的 Visual Studio 为 2008~2022。Visual Studio 17 2022 生成器开头的星号表示,在不指定生成器参数的情况下,该生成器便是默认生成器。如果我们不想使用默认生成器,便可以使用 CMake 的 -G 参数来指定生成器类别。例如:使用 VS2022 作为生成器:cmake -G "Visual Studio 17 2022"使用 VS2019 作为生成器:cmake -G "Visual Studio 16 2019"如果我们要指定生成的程序或库的位数该怎么办?可以再加一个 -A 参数。使用 VS2022 作为生成器,32 位构建:cmake -G "Visual Studio 17 2022" -A Win32使用 VS2022 作为生成器,64 位构建:cmake -G "Visual Studio 17 2022" -A x64细心的读者可能注意到,如果 Visual Studio 版本低于 VS2019(比如:VS2010、VS2017 等),则生成器名称里有一个可选的 [arch] 占位符。以 VS2017 为例: Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files. Optional [arch] can be "Win64" or "ARM".这表示,你可以这样指定生成器:cmake -G "Visual Studio 15 2017"或是:cmake -G "Visual Studio 15 2017 Win64"或是:cmake -G "Visual Studio 15 2017 ARM"分别对应 x86、x64、ARM 架构。这里简单总结一下:在 VS2019 之前,我们可以通过在生成器名称里增加可选的 [arch] 来指定目标架构。从 VS2019 开始,则是通过 -A 来指定目标架构。如果配置(Configure)成功的话,上述这些命令最终会帮你生成(Generate)对应版本的 Visual Studio 解决方案&工程文件。接下来,你就可以用对应版本的 Visual Studio 打开解决方案文件,一键编译即可。如果你想直接通过 cmake 来发起 Build,可以:cmake --build --config \<Config> --target \<Target>这里:<build 目录> 要输入实际的 build 目录。<Config> 用于设置 Debug 或 Release 模式。<Target> 则用于指定生成目标的名称。如果你想编译所有目标,可以忽略 --target <Target>。使用 NMake 生成器:cmake -G "NMake Makefiles"生成成功后,可以使用 MSVC 的 nmake 来构建项目。如果提示找不到 nmake,可以尝试从 VS 提供的开发人员命令提示符(Developer Command Prompt)运行这些命令。如果你想要使用 MinGW,则可以指定:cmake -G "MinGW Makefiles"然后运行:mingw32-make即可。注意:上面的这些命令均未指定 -S、-B 参数,具体操作时,记得加上。接下来,简单介绍一下 CMake 的 -D 参数。在 Configure 阶段,-D 参数发挥着重要的作用。-D 参数类似于编程语言里定义/设置一个变量的值。这些“变量”,有些是 CMake 预定义的(大部分以 CMAKE 开头,如:CMAKE_INSTALL_PREFIX、CMAKE_PREFIX_PATH),有些则是开发人员在 CMakeLists.txt 中使用 option 定义的一些编译开关项(比如:PyStand 的 CMakeLists.txt 里的 PYSTAND_CONSOLE)。在 Configure 阶段,通过 -D 参数便可以影响到最终 Generate 得到的结果。下面举一些例子。大部分同时支持动态库和静态库的 C、C++ 项目的 CMakeLists.txt 可能会根据 BUILD_SHARED_LIBS 来决定是生成动态库还是静态库。生成动态库:cmake -DBUILD_SHARED_LIBS=ON生成静态库:cmake -DBUILD_SHARED_LIBS=OFF指定目标安装路径:cmake -DCMAKE_INSTALL_PREFIX=\<install path>PyStand 则定义了 PYSTAND_CONSOLE,其默认值为 OFF。如果想要将 PyStand 编译为一个控制台项目,则需要在 Configure 阶段指定:cmake -DPYSTAND_CONSOLE=ON经过了上面的介绍,相信你已掌握了 CMake 命令行的基本用法。接下来,让我们实操一下:下载 PyStand 源码后,cd 到源码的目录下,我们就可以用 CMake 来构建自己的 PyStand 了。cd PyStandmkdir buildcd build构建 32 位版本的 PyStand:cmake .. -A Win32构建 64 位版本的 PyStand:cmake .. -A x64PyStand 默认为 GUI 应用。如果我们想构建控制台版的 PyStand,只需要在配置阶段加上 -DPYSTAND_CONSOLE=ON 参数即可:cmake .. -A x64 -DPYSTAND_CONSOLE=ON配置完成后,即可生成 PyStand.exe:cmake --build . --config Release如果想要替换 PyStand 的图标,可以把 PyStand 目录下的 appicon.ico 替换为自己想要使用的图标(文件名要一致)。或者,将你要使用的图标复制到 PyStand 源码目录下,然后用文本编辑器编辑 resource.rc,将其中的图标文件名改为对应名称即可。ViTables 的图标文件在 vitables\icons\mswindows 路径下,读者可以自己尝试一下。此外,经过稍许改动,读者也可以将 PyStand.int 中的启动代码直接嵌入到 PyStand.exe 中。感兴趣的读者可以尝试一下。最后与其它几种主流打包方案相比,使用 PyStand 打包应用的自主可控性较高,你有很大的自由度对你的包进行裁剪,以尽量减小打包后程序的总体积。PyStand 生来就不是为了将你的 Python 程序打包成一个独立的 exe 的。如果你需要将你的 Python 应用打包为单个 exe 文件,可以考虑 PyInstaller、Nuitka、py2exe,亦或是 cx_Freeze 结合 UPX。在使用 PyInstaller 等工具时,你也可以了解一下其工作原理,具体参考韦易笑大神在知乎上的回答。如果你想“加密”你的 Python 源码,亦或增加反编译的难度,也可以参考韦易笑大神在知乎上的回答.
2023年06月07日
23 阅读
5 评论
0 点赞
2023-06-06
python打包-pyinstaller快速上手
PyInstaller 快速入门1. 写在前面PyInstaller简介通过 PyInstaller,可以将 Python 脚本打包成 .exe 文件(适用于 Windows)或适用于 macOS和 Linux 的可执行文件,用户无需安装 Python 或任何相关依赖,便能直接运行程序。主要优势:将 Python 脚本打包成独立可执行文件,方便分发和运行。支持单文件打包、图标定制、以及额外文件的捆绑。可选隐藏控制台窗口,适合图形化应用(GUI)程序。适用场景:发布桌面工具或命令行程序。让没有 Python 环境的用户也能使用你的工具。分享自包含的 Python 项目,确保目标机器能够顺利运行。PyInstaller github仓库地址为:https://github.com/pyinstaller/pyinstallerPyInstaller 使用指南中文翻译的github仓库地址为:https://github.com/muziing/pyinstaller-docs-zh-cn打包原理简述pyinstaller先读取你需要打包的python文件,然后搜索其中使用的模块,然后将所需的模块以及Python解释器放到一起,并通过一些操作构建exe,最终形成你的应用程序。当然,在搜索模块的时候可能会遇到一些问题。例如pyinstaller只会搜索import语句,然后根据import得到的模块再进行搜索。如果编程者使用了一些特殊的导入方式,比如使用\__import\_\_()函数,使用importlib里面的导入函数,那么pyinstaller很可能找不到你所需要的模块。这时,你可以通过参数来指定你所需要的模块,也可以使用“HOOK钩子”等等。打包效果概述pyinstaller打包后会形成一个文件夹或单个的exe(可以用参数指定)。但不论是哪一种情况,都会包含一个exe文件,用户可以双击它运行该应用程序。假如你要打包myscript.py,那么打包完成后运行这个myscript.exe,效果就是运行myscript.py后的效果。默认情况下,打开打包后的程序,会打开一个黑色窗口的控制台(cmd的样子),可以通过打包命令中的参数控制显隐,默认会显示(如果不通过 input() 等待输入等手段控制,执行完程序,窗口会自动关闭),当你制作GUI程序的时候,可以选择隐藏控制台,来提升用户体验。这个控制台用于为python提供标准输入(stdin),标准输出(stdout),标准错误(stderr)。也就是说,这个控制台上显示了print函数的输出,用于接收input函数的输入,还会输出python的异常。如果你隐藏了这个控制台,程序中的print就无法显示(但是不会报错),报错信息也无法被用户直接看到(pyinstaller有一些选项来控制显示异常),需要注意的是,此时不能使用input,否则会报错:RuntimeError: input(): lost sys.stdinpython文件有一种后缀名*.pyw,这样的程序执行时默认会隐藏控制台。如果将文件后缀命名为pyw,那么pyinstaller也会认为它隐藏了控制台,不需要通过额外的选项来指定。直接打包后的文件会被反编译(即通过exe文件得到原来的代码),没有任何安全性,可以通过一些方法进行加密。打包成单个文件夹下面介绍一下打包完成后形成的文件夹。这个文件夹的名字是你提供的,一般是你要求打包的python文件的名称。文件夹中包含一个exe文件,以及其他一些依赖文件(比如一些dll文件,可能还有你的应用所需要的图片等素材)。你只需要将该文件夹压缩就能发给别人运行了。当你运行里面的exe文件后,pyinstaller其实只是启动了解释器,然后通过解释器运行你的主程序。优点打包成单个文件夹的形式便于调试,因为你可以清楚地看到pyinstaller将哪些模块文件放到了文件夹中。当你更改代码,需要用户更新应用时,只需要让用户对于部分内容进行修改。如果你只修改了主程序,没有使用多余的模块,那么就只需要让用户替换里面的exe文件,而不用全部替换(因为更新前后使用的模块是一致的,它们都以多文件的形式放到了文件夹中)。单个文件夹的状态下,程序的启动速度和打包前差不多。缺点打包成单个的文件夹后,文件大小可能会更大一些,因为大部分依赖文件没有进行压缩。打包成单个exe单个exe模式下,pyinstaller只会生成一个单独的exe文件,所有的依赖文件都会被压缩到exe文件中。和上面的文件夹模式类似,exe启动后,pyinstaller也是通过调用python解释器来运行主程序的。优点启动单个exe非常简单,用户只需要点击exe文件就能运行,而无需在一大堆的依赖文件中找到exe文件。并且在经过压缩后,这个exe文件的文件大小会大大减小。缺点单个exe的启动速度比较慢(通常会慢几秒,且只是启动时的速度,不是运行后的速度),这是因为pyinstaller会在这一段时间中将一些依赖文件写入到一个临时的文件夹(后文介绍该文件夹的调用方式)。如果你希望添加一些附带文件(比如使用说明README),你还需要额外新建文件夹并将其放进去。2.打包基础教程可视化界面打包下面描述的这些命令行参数,对于用户来说并不友好,所以有热心网友开发了GUI工具(python包的形式),可以一键式配置,推荐使用:https://github.com/brentvollebregt/auto-py-to-exepip install auto-py-to-exe auto-py-to-exeA.打包生成内容在项目根目录,打开命令行窗口执行命令:pyinstaller 项目入口函数 即可进行打包,主要生成以下三个内容(生成后,除了dist文件夹,其它都可以删除):*.spec 文件:*.spec 文件是 PyInstaller 用于配置打包过程的脚本文件。每个 .spec 文件对应一个 Python 脚本,并包含了打包过程中所需的各种配置选项。通过编辑 .spec 文件,你可以自定义打包行为,例如指定额外的数据文件、隐藏导入模块、设置输出路径等。build/ 文件夹:用于构建可执行文件,其中给出了该程序中间生成的一些东西。其中有一个文件提示了没有找到的库、被忽略的库等信息,但这只是作为一个参考。没找到会被忽略了,并不一定影响最后程序的运行,还要看最后exe的结果来说。dist/ 文件夹:包含应用程序的所有依赖项和可执行文件,也就是打包后,最终生成的可以对外分享的内容。B.打包常用参数这只是一些常用的PyInstaller参数,实际上有更多选项可用于更复杂的定制。你可以使用pyinstaller --help命令来查看完整的参数列表和说明。参数名简称描述--onefile-F将所有依赖文件打包为单个可执行文件。--onedir-D生成一个目录,包含多个文件。--windowed或`--noconsole` -w隐藏控制台窗口(仅win下生效)。--console-c显示控制台(仅win下生效)。--name-m指定生成的可执行文件名称。--add-data 捆绑额外文件或文件夹(如配置文件、静态资源等)。<SRC;DEST or SRC:DEST>--add-binary 和--add-data类似,不过指定的文件夹或文件是二进制的。<SRC;DEST or SRC:DEST>--path-p提供一个路径进行搜索并且导入里面的模块(不同的路径使用路径分隔符os.pathsep分隔开,或者多次使用这个参数)。--hidden-import 手动添加隐藏的依赖模块(通常是自动检测遗漏的依赖)。需要进行额外导入的模块。当pyinstaller在程序中找不到一些模块时,需要你额外指定。这个参数可以多次使用,可以解决一些模块找不到的问题。指定需要手动导入但不在源代码中明确导入的模块。--icon-i设置可执行文件的图标(需提供 .ico 文件)。--upx-dir 指定UPX可执行文件压缩工具的目录。--version-file 指定版本信息文件--debug-d提供debug输出。--optimize-O使用优化编译Python文件。--noconfirm 禁用优化编译确认提示。--help-hpyinstaller有很多参数,可以用-h或--help参数查看帮助--noconfirm 在覆盖现有输出目录时不进行确认。--clean 清理之前的构建缓存,强制重新打包。--specpath 指定spec文件的生成目录,默认为当前目录。--exclude-module 排除某些模块。--python 指定python解释器的路径。--splash IMAGE_FILE 添加一个启动画面(图片文件)路径,在程序运行前显示指定的启动图片,起到加载提示的效果。--uac-admin 启动打包后的程序时申请以管理员模式运行(仅Windows)C. 基础步骤1. 安装 PyInstaller在终端(或命令行)中运行以下命令,安装 PyInstaller,注意要装到对应的Python环境中:pip install pyinstaller2. 使用基础命令进行打包假设你有一个 Python 脚本 example_script.py,使用下面的命令将其打包为一个独立的可执行文件:pyinstaller example_script.py打包后,可以在 dist 目录下找到生成的可执行文件,其他文件可以删除不用。D. 常见用法示例 1:打包成单个EXE文件将 example_script.py 所有依赖项和代码打包成一个单一的 .exe 文件pyinstaller --onefile example_script.py 或者 pyinstaller -F example_script.py示例 2:隐藏控制台窗口适用于图形界面(GUI)应用程序,运行时隐藏控制台窗口pyinstaller --onefile --noconsole gui_app.py示例 3:自定义名称和图标将输出文件命名为 my_program.exe,并指定图标文件为 app.icopyinstaller --onefile --name=my_program --icon=app.ico example_script.py示例 4:捆绑额外文件将配置文件 config.yaml 一起捆绑进可执行文件:pyinstaller --onefile --add-data "config.yaml;." example_script.py注意:路径问题:使用 --add-data 时,不同操作系统的路径分隔符需特别注意,在 Windows 系统中,路径分隔符用分号 ;,而在 macOS/Linux中使用冒号 :Windows:"source;destination"macOS/Linux:"source:destination"再例如你的程序依赖于外部数据文件(如图片、配置文件等),你需要确保这些数据文件也被包含在内pyinstaller --onefile --add-data "data;./data" example_script.py这里,data;./data意味着将当前目录下的data文件夹及其内容添加到打包的EXE中,并在程序运行时作为./data路径访问。示例 5:解决控制台自动关闭问题如果你想在程序运行时捕获并保持控制台窗口打开,可以在程序中添加一个暂停的操作,例如 input() 或 raw_input()。例如:if __name__ == '__main__': print("Press Enter to exit...") input()另一种方法是使用 subprocess 模块启动一个新的控制台窗口来运行程序,这样程序运行结束后控制台不会自动关闭。例如:import subprocess import sys if __name__ == '__main__': subprocess.Popen([sys.executable, __file__], creationflags=subprocess.CREATE_NEW_CONSOLE)示例 6:解决缺失依赖问题如果在运行时遇到某个模块丢失的错误,可以通过 --hidden-import 指定手动引入依赖:pyinstaller --hidden-import=requests example_script.pyE. 常见问题1.打包的体积非常大因为 pyinstaller 打包方法是将被打包的.py文件所处的虚拟环境中所有的数据(包)一起打包,所以可能导致打包成的exe程序非常大,因此可以另外单独为需要打包的软件创建一个虚拟环境,在新创的虚拟环境中只安装需要使用的包,从而缩小exe程序文件的大小。另外,使用UPX压缩程序也是个好办法,把upx放到python环境的Script目录里时,打包会默认使用(使用upx打包时间会长一些,个别场景下,upx可能会有dll丢失错误 )UPX发布:https://upx.github.io/3.96版本的win64版本下载地址:https://github.com/upx/upx/releases/download/v3.96/upx-3.96-win64.zip打包体积问题是个经久不衰的题目,除了以上描述,还有非常多的方法,这里不再赘述,只列出来常见思路:知乎讨论帖:https://www.zhihu.com/question/281858271推荐使用Nuitka封装,不要使用pyinstaller https://nuitka-cn.com/使用pip install fspacker完成打包,自动完成最小依赖发布 https://pypi.org/project/fspacker/使用pip install soeasypack 来瘦身,获得最小依赖包 https://zhuanlan.zhihu.com/p/13398475275?utm_psn=1852841488821653504使用更小的嵌入式 Python 版本来打包 https://www.zhihu.com/question/48776632/answer/23366546492.打包版本不正确我在虚拟环境ven1里使用pyinstaller 为什么打包的Python版本不是ven1里面的?最终原因发现,之前在虚拟环境安装pyinstaller的时候,似乎安装异常,只在lib下有pyinstaller。py,在scripts文件夹下没有pyinstaller.exe,打包时,要调用的是这个exe,重新安装一遍即可,或者使用如下方案:1.使用绝对路径调用 pyinstallerWindows:D:\Code\PID\ven1\Scripts\pyinstaller.exe main.pyLinux/macOS:/path/to/ven1/bin/pyinstaller main.py2.通过指定 Python 解释器来运行 pyinstaller,确保使用的是虚拟环境中的解释器。通过指定 Python 解释器来运行 `pyinstaller`,确保使用的是虚拟环境中的解释器 python -m pyinstaller main.py3.终端控制台输出带颜色字体方式一 、通过ANSI转义码实现# 输出红色文本示例 print("\033[91mHello, world!\033[0m") # 输出绿色文本示例 print("\033[92mHello, world!\033[0m")转义码描述\033[0m关闭所有属性\033[1m设置高亮单独\033[2m设置一半亮度\033[3m斜体\033[4m下划线\033[5m闪烁\033[7m反显\033[8m消隐\033[30m设置前景色为黑色\033[31m设置前景色为红色\033[32m设置前景色为绿色\033[33m设置前景色为黄色\033[34m设置前景色为蓝色\033[35m设置前景色为紫色\033[36m设置前景色为青色\033[37m设置前景色为白色\033[40m设置背景色为黑色\033[41m设置背景色为红色\033[42m设置背景色为绿色\033[43m设置背景色为黄色\033[44m设置背景色为蓝色\033[45m设置背景色为紫色\033[46m设置背景色为青色\033[47m设置背景色为白色方式二、使用termcolor库要在终端输出彩色文字,我们可以使用 termcolor 库中的 colored 方法。该方法需要传入两个参数:要输出的文字以及文字颜色。pip install termcolor from termcolor import colored print(colored('Hello, World!', 'red')) #执行上述代码,会在终端中输出红色的“Hello, World!”字样。 #如果要修改背景颜色,只需要在第二个参数中指定背景颜色即可。例如,下面的代码将输出红底白字的“Error!”字样: print(colored('Error!', 'white', 'on_red'))问题解决:Python 使用pyinstaller打包后,print打印颜色乱码#代码如下,直接运行是正常的,使用pyinstaller打包后运行乱码 class bcolors: OKRED = '\033[1;31m' END = '\033[0m' print(bcolors.OKRED+'红色字体'+bcolors.OKRED) #添加如下代码即可解决: import colorama colorama.init(autoreset=True)3.帮助文档 pyinstaller -h 位置参数: scriptname 要处理的脚本文件名或确切的一个 .spec 文件。如果指定了 .spec 文件,大部分选项都是不必要的并且会被忽略。 选项: -h, --help 显示此帮助信息并退出 -v, --version 显示程序版本信息并退出 --distpath DIR DIR是打包应用存放的位置(默认:./dist) --workpath WORKPATH WORKPATH是所有临时工作文件(如.log.pyz等)存放的位置(默认:./build) -y, --noconfirm 在不询问确认的情况下替换输出目录(默认:SPECPATH\dist\SPECNAME) --upx-dir UPX_DIR UPX_DIR是UPX 工具的路径(默认:搜索执行路径) --clean 在构建前清理 PyInstaller 缓存和移除临时文件。 --log-level LEVEL 构建时控制台消息的详细程度。LEVEL 可以是 TRACE, DEBUG, INFO, WARN, DEPRECATION, ERROR, FATAL 中的一个(默认:INFO)。也可以通过 PYI_LOG_LEVEL 环境变量设置并覆盖。 要生成什么: -D, --onedir 创建一个包含可执行文件的单文件夹捆绑包(默认) -F, --onefile 创建一个单文件捆绑的可执行文件。 --specpath DIR DIR是存放生成的 spec 文件的文件夹(默认:当前目录) -n NAME, --name NAME NAME是为打包的应用和生成的spec文件分配的名称(默认:第一个脚本的基本名称) --contents-directory CONTENTS_DIRECTORY 仅对于 onedir 构建,指定所有支持文件(即除了可执行文件本身之外的所有内容)将被放置的目录名称。使用 "." 重新启用没有内容目录的老 onedir 布局。 要捆绑什么,在哪里搜索: --add-data SOURCE:DEST 要添加到应用程序的额外数据文件或包含数据文件的目录。参数值应该是 "源:目标目录" 的形式,其中源是要收集的文件(或目录)的路径,目标目录是相对于顶级应用目录的目标目录,两个路径用冒号(:)分隔。要将文件放在顶级应用目录中,使用 . 作为目标目录。这个选项可以多次使用。 --add-binary SOURCE:DEST 要添加到可执行文件的额外二进制文件。参见 ``--add-data`` 选项的格式。这个选项可以多次使用。 -p DIR, --paths DIR 搜索导入的路径(类似于使用 PYTHONPATH)。允许多个路径,用 ``';'`` 分隔,或者多次使用这个选项。等同于在 spec 文件中提供 ``pathex`` 参数。 --hidden-import MODULENAME, --hiddenimport MODULENAME 命名一个在脚本的代码中不可见的导入。这个选项可以多次使用。 --collect-submodules MODULENAME 从指定的包或模块中收集所有子模块。这个选项可以多次使用。 --collect-data MODULENAME, --collect-datas MODULENAME 从指定的包或模块中收集所有数据。这个选项可以多次使用。 --collect-binaries MODULENAME 从指定的包或模块中收集所有二进制文件。这个选项可以多次使用。 --collect-all MODULENAME 从指定的包或模块中收集所有子模块、数据文件和二进制文件。这个选项可以多次使用。 --copy-metadata PACKAGENAME 复制指定包的元数据。这个选项可以多次使用。 --recursive-copy-metadata PACKAGENAME 复制指定包及其所有依赖项的元数据。这个选项可以多次使用。 --additional-hooks-dir HOOKSPATH 额外的搜索钩子的路径。这个选项可以多次使用。 --runtime-hook RUNTIME_HOOKS 自定义运行时钩子文件的路径。运行时钩子是与可执行文件一起捆绑的代码,并在任何其他代码或模块执行之前执行以设置运行时环境的特殊功能。这个选项可以多次使用。 --exclude-module EXCLUDES 可选的模块或包(Python 名称,不是路径名称)将被忽略(就好像它没有找到)。这个选项可以多次使用。 --splash IMAGE_FILE (实验性)向应用程序添加带有 IMAGE_FILE 图片的启动画面。启动画面可以在解包时显示进度更新。 如何生成: -d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive} 为调试冻结应用提供帮助。这个参数可以多次提供以选择以下几个选项中的几个。 - all: 下面三个选项的全部。 - imports: 指定 -v 选项给底层 Python 解释器,导致它每次初始化模块时打印消息,显示它从哪里(文件名或内置模块)加载。详见 https://docs.python.org/3/using/cmdline.html##id4. - bootloader: 告诉引导程序在初始化和启动捆绑的应用时发出进度消息。用于诊断缺少导入的问题。 - noarchive: 将所有冻结的 Python 源文件存储为结果可执行文件内部的归档,而不是将它们作为文件存储在结果输出目录中。 --optimize LEVEL 收集的 python 模块和脚本使用的字节码优化级别。详情见 PyInstaller 手册中的 “字节码优化级别” 部分。 --python-option PYTHON_OPTION 指定在运行时传递给 Python 解释器的命令行选项。当前支持 "v"(等同于 "--debug imports"),"u","W <警告控制>","X <xoption>" 和 "hash_seed=<值>"。详情见 PyInstaller 手册中的 “指定 Python 解释器选项” 部分。 -s, --strip 对可执行文件和共享库应用符号表剥离(Windows 不建议) --noupx 即使可用也不使用 UPX(在 Windows 和 *nix 之间工作方式不同) --upx-exclude FILE 在使用 upx 时防止二进制文件被压缩。这通常用于如果 upx 在压缩期间损坏某些二进制文件。FILE 是二进制文件的文件名,不带路径。这个选项可以多次使用。 Windows 和 Mac OS X 特定选项: -c, --console, --nowindowed 打开控制台窗口进行标准 I/O(默认)。在 Windows 上,如果第一个脚本是 '.pyw' 文件,此选项无效。 -w, --windowed, --noconsole Windows 和 Mac OS X:不提供控制台窗口进行标准 I/O。在 Mac OS 上,这也触发构建 Mac OS .app 捆绑包。在 Windows 上,如果第一个脚本是 '.pyw' 文件,此选项自动设置。在 *NIX 系统上忽略此选项。 --hide-console {minimize-late,hide-early,hide-late,minimize-early} 仅限 Windows:在控制台启用的可执行文件中,如果程序拥有控制台窗口(即,不是从现有控制台窗口启动的),引导程序自动隐藏或最小化控制台窗口。 -i <FILE.ico 或 FILE.exe,ID 或 FILE.icns 或 图片 或 "NONE">, --icon <FILE.ico 或 FILE.exe,ID 或 FILE.icns 或 图片 或 "NONE"> FILE.ico:将图标应用于 Windows 可执行文件。FILE.exe,ID:从 exe 中提取 ID 的图标。FILE.icns:将图标应用于 Mac OS 上的.app 捆绑包。如果输入的图片文件不是平台格式(Windows 上的 ico,Mac 上的 icns),PyInstaller 尝试使用 Pillow 将图标转换为正确的格式(如果安装了 Pillow)。使用 "NONE" 不应用任何图标,从而使 OS 显示一些默认图标(默认:应用 PyInstaller 的图标)。这个选项可以多次使用。 --disable-windowed-traceback 在窗口化(无控制台)模式下禁用未处理异常的 traceback 转储(仅限 Windows 和 macOS),并显示一条消息表明此功能已被禁用。 Windows 特定选项: --version-file FILE 向 exe 添加 FILE 的版本资源。 --manifest <FILE 或 XML> 向 exe 添加 FILE 或 XML 清单。 -m <FILE 或 XML> --manifest 的过时简写。 -r RESOURCE, --resource RESOURCE 向 Windows 可执行文件添加或更新资源。RESOURCE 是一到四个项目,FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE 可以是数据文件或 exe/dll。对于数据文件,至少必须指定 TYPE 和 NAME。LANGUAGE 默认为 0,也可以指定为通配符 * 以更新给定 TYPE 和 NAME 的所有资源。对于 exe/dll 文件,如果省略 TYPE,NAME 和 LANGUAGE 或指定为通配符 *,FILE 中的所有资源将被添加/更新到最终可执行文件中。这个选项可以多次使用。 --uac-admin 使用此选项会创建一个清单,将在应用程序启动时请求提升权限。 --uac-uiaccess 使用此选项允许提升的应用程序与远程桌面工作。 Mac OS 特定选项: --argv-emulation 为 macOS 应用捆绑包启用 argv 仿真。如果启用,初始打开文档/URL 事件由引导程序处理,并且传递的文件路径或 URL 被追加到 sys.argv。 --osx-bundle-identifier BUNDLE_IDENTIFIER Mac OS .app 捆绑包标识符用作代码签名目的的默认唯一程序名称。通常形式是反向 DNS 表示法的层次名称。例如:com.mycompany.department.appname(默认:第一个脚本的基本名称) --target-architecture ARCH, --target-arch ARCH 目标架构(仅限 macOS;有效值:x86_64, arm64, universal2)。启用在 universal2 和冻结应用的单架构版本之间切换(提供的 Python 安装支持目标架构)。如果没有指定目标架构,将针对当前运行的架构。 --codesign-identity IDENTITY 代码签名身份(仅限 macOS)。使用提供的身份对收集的二进制文件和生成的可执行文件进行签名。如果未提供签名身份,则执行临时签名。 --osx-entitlements-file FILENAME 代码签名收集的二进制文件时使用的权限文件(仅限 macOS)。 很少使用的特殊选项: --runtime-tmpdir PATH 在 onefile 模式下提取库和支持文件的位置。如果提供了这个选项,引导程序将忽略运行时操作系统定义的任何临时文件夹位置。_MEIxxxxxx 文件夹将在此位置创建。请仅在您知道自己在做什么时使用此选项。注意 在 POSIX 系统上,PyInstaller 的引导程序不对给定的路径字符串执行 shell 风格的环境变量扩展。因此,使用环境变量(例如,~ 或 $HOME)在路径中将不起作用。 --bootloader-ignore-signals 告诉引导程序忽略信号而不是将其转发给子进程。在例如一个监督进程同时向引导程序和子进程(例如,通过进程组)发送信号的情况下很有用,以避免两次向子进程发送信号。
2023年06月06日
18 阅读
5 评论
0 点赞
2023-06-05
python打包-Nuitka快速上手
一、Nuitka介绍打包思路1.pyinstaller:简单,成功率高,但是能直接被解译。(优点:简单、成功率高;缺点:容易被破解看到源码)2.cx\_freeze:不太追求性能,只是为了将代码编译。(优点:不被破解看到源码;缺点:比nuitka速度慢)3.Nuitka:追求速度,且不被反编译直接看到源码。(优点:性能更快;缺点:成功率低,需要一些稳定的版本)Nuitka介绍官方手册:https://nuitka.net/user-documentation/民间手册:https://jwndv2g391c.feishu.cn/wiki/Kqh1w1CeMis64HkLb4Lc6ODknob增强工具:https://blog.csdn.net/loujiand/article/details/129051444二、Nuitka打包环境准备安装Nuitka包pip install nuitka版本很重要,有一些版本不稳定,按照通用打包命令运行时,如果有什么异常,可以考虑往前几个版本试试,当前我在用2.5.8安装C编译环境C编译环境概述MinGW简介MinGW (Minimalist GNU on Windows):实际上是将gcc(c/c++编译器)移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。而且还可以使用一些 Windows 不具备的,Linux平台下的开发工具。编辑器:编辑修改和产生文件时所使用的软件。编译器:编译是从源代码(通常为高级语言)到能直接被计算机执行的目标代码(通常为低级语言或机器语言)的翻译过程。解释器:把高级编程语言一行一行直接转译运行。如果再执行那就再一行行翻译,不保留翻译后的可以运行的二进制代码。Nuitka对MinGW的要求Windows 上的 MinGW64 C11 编译器,必须基于 gcc 11.2 或更高。如果没有找到可用的 C 编译器,它将被自动下载。在所有其他平台上,至少使用 5.1 版的 gcc 编译器,低于此版本的 g++ 编译器至少使用 4.4 版作为替代。macOS X 和大多数 FreeBSD 架构上的 clang 编译器。在 Windows 上,如果 Visual Studio 安装程序提供,可以使用 Windows 上的 clang-cl 编译器所有版本的下载地址https://github.com/brechtsanders/winlibs_mingw/releases/简单说:nuitka打包需要c环境,windows推荐使用mingw64来构建c环境,注意新的版本或许会有报错,Nuitka 对特定版本的winlibs-gcc有严格依赖,它期望使用精确匹配的版本来进行相关的编译等操作。当前我在用12.2.0,打包成功率较高,完整的名称和下载地址是winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-16.0.0-mingw-w64ucrt-10.0.0-r5.zip。文件清单x86_64-posix-sjlj x86_64-posix-seh x86_64-win32-sjlj x86_64-win32-seh i686-posix-sjlj i686-posix-dwarf i686-win32-sjlj i686-win32-dwarf释义1:DWARF:一种带调试信息(DWARF- 2(DW2)EH)的包, 所以比一般的包尺寸大,仅支持32位系统SJLJ:跨平台,支持32,64位系统,缺点是:运行速度稍慢,GCC不支持SEH: 调用系统机制处理异常,支持32,64位系统,缺点是:Gcc新版才支持释义2:x86_64: 简称X64,64位操作系统i686: 32位操作系统 (i386的子集),差不多奔腾2(1997年5月)之后的CPU都是可以用的;释义3:posix: 启用了C++ 11 多线程特性win32: 未启用 (从时间线上正在尝试也启用部分 Treading)区别DWARF DWARF- 2(DW2)EH ,这需要使用DWARF-2(或DWARF-3)调试信息。 DW-2 EH可以导致可执行文件略显膨胀,因为大的调用堆栈解开表必须包含在可执行文件中。setjmp / longjmp(SJLJ)。基于SJLJ的EH比DW2 EH慢得多(在没有异常时会惩罚甚至正常执行),但是可以在没有使用GCC编译的代码或没有调用堆栈的代码上工作。结构化异常处理(SEH) (Structured Exception Handling)Windows使用自己的异常安装MinGW通过Nuitka自动安装1.在Python环境中安装nuitka,然后用其打包一个Python文件pip install nuitka nuitka main.py2.执行后,信息如下,表示Nuitka询问是否安装它指定版本的MinGW64(版本是14.2.0posix-19.1.1-12.0.0-msvcrt-r2),无论是否同意安装,此时它会在提示的路径下创建一个同名文件夹。(base) (ven1) PS D:\Code\PID> nuitka main.py Nuitka-Options: Used command line options: main.py Nuitka-Options:WARNING: You did not specify to follow or include anything but main program. Check options and make sure that is intended. Nuitka: Starting Python compilation with Nuitka '2.5.7' on Python '3.11' commercial grade 'not installed'. Nuitka: Completed Python level compilation and optimization. Nuitka: Generating source code for C backend compiler. Nuitka: Running data composer tool for optimal constant value handling. Nuitka: Running C compilation via Scons. Nuitka will use gcc from MinGW64 of winlibs to compile on Windows. Is it OK to download and put it in 'C:\Users\ADMINI~1\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2'. Fully automatic, cached. Proceed and download? [Yes]/No : 3.如果输入yes后回车,就会下载该版本到提示的路径,然后自动解压出来(此时下载的压缩包可以手动删掉,不会影响),然后继续进行打包动作,然而,在它指定的这个版本下,报错了。Nuitka: Downloading 'https://github.com/brechtsanders/winlibs_mingw/releases/download/14.2.0posix-19.1.1-12.0.0-msvcrt-r2/winlibs-x86_64-posix-seh-gcc-14.2.0-llvm-19.1.1-mingw-w64msvcrt-12.0.0-r2.zip'. Nuitka: Extracting to 'C:\Users\ADMINI~1\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe' Nuitka-Scons: Backend C compiler: gcc (gcc 14.2.0). terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: Cannot convert character sequence: Illegal byte sequence scons: *** [module.__main__.o] Error 3 terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: Cannot convert character sequence: Illegal byte sequence scons: *** [__loader.o] Error 3 terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: Cannot convert character sequence: Illegal byte sequence terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: Cannot convert character sequence: Illegal byte sequence scons: *** [__constants.o] Error 3 scons: *** [__helpers.o] Error 3 FATAL: Failed unexpectedly in Scons C backend compilation. Nuitka:WARNING: Complex topic! More information can be found at https://nuitka.net/info/scons-backend-failure.html Nuitka-Reports: Compilation crash report written to file 'nuitka-crash-report.xml'. 4.难道是安装的有问题吗?通过nuitka --version查看版本,发现安装的确实是它自己推荐的版本14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe (gcc 14.2.0)。也就是说,nuitka推荐的版本可能也会有问题,所以网络上很多教程都强调,只安装大家已经验证过没有问题的版本,不要追求最新版。(base) (ven1) PS D:\Code\PID> nuitka --version 2.5.8 Commercial: None Python: 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] Flavor: CPython Official Executable: D:\Code\打包测试\ven1\Scripts\python.exe OS: Windows Arch: x86_64 WindowsRelease: 10 Nuitka-Scons: Non downloaded winlibs-gcc 'C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\gcc\x86_64\x86_64-14.2.0-release-posix-seh-ucrt-rt_v12-rev0\mingw64\bin\gcc.exe' is being ignored, Nuitka is very dependent on the precise one. Version C compiler: ~\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe (gcc 14.2.0). (base) (ven1) PS D:\Code\PID> 5.如果此时手动下载其他版本后(例如winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-16.0.0-mingw-w64ucrt-10.0.0-r5)解压到指定的目录的同级目录下,无论加不加环境变量,还是会提示不可用,坚持要下载它指定的版本,此时的解决办法是,把你下载解压得到的MinGW文件夹放到它指定版本的文件夹目录下替换,此时再重新打包即可。可以继续查看下命令,就会发现文件夹还是14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe ,但是gcc的版本已经变成了 (gcc 12.2.0)。(base) (ven1) PS D:\Code\PID> nuitka --version 2.5.8 Commercial: None Python: 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] Flavor: CPython Official Executable: D:\Code\打包测试\ven1\Scripts\python.exe OS: Windows Arch: x86_64 WindowsRelease: 10 Version C compiler: ~\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe (gcc 12.2.0). (base) (ven1) PS D:\Code\PID> 官方文档中说要设置一下环境变量,实际使用过程中发现不设置也可以正常使用手动下载并配置环境变量注意:如下方案,似乎在新版本的nuitka中并不生效,即便配置了环境变量或者使用--mingw参数,nuitka也会强制要求下载它的指定版本下载地址:https://github.com/brechtsanders/winlibs_mingw/releases/配置环境变量打开控制面板,依次选择 系统和安全、系统、高级系统设置、高级、环境变量在系统变量中新增一条 MINGW\_HOME=xxx\mingw64(xxx\mingw64 为解压路径)编辑 系统变量 Path,在最后增加一条数据:%MINGW\_HOME%\bin 配置测试:win+R进入命令行模式,输入 gcc -v 可以在最后一行看到当前安装的版本C:\Users\Administrator>gcc -v Using built-in specs. COLLECT_GCC=C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe COLLECT_LTO_WRAPPER=c:/users/administrator/appdata/local/nuitka/nuitka/cache/downloads/gcc/x86_64/14.2.0posix-19.1.1-12.0.0-msvcrt-r2/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/12.2.0/lto-wrapper.exe OFFLOAD_TARGET_NAMES=nvptx-none Target: x86_64-w64-mingw32 Configured with: ../configure --prefix=/R/winlibs64ucrt_stage/inst_gcc-12.2.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --disable-libstdcxx-debug --disable-version-specific-runtime-libs --with-stabs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++,jit --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --enable-libstdcxx-time --enable-libstdcxx-pch --with-mpc=/d/Prog/winlibs64ucrt_stage/custombuilt --with-mpfr=/d/Prog/winlibs64ucrt_stage/custombuilt --with-gmp=/d/Prog/winlibs64ucrt_stage/custombuilt --with-isl=/d/Prog/winlibs64ucrt_stage/custombuilt --enable-libstdcxx-backtrace --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --enable-clocale=generic --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs64ucrt_stage/gcc-12.2.0/build_mingw/mingw-w64 CFLAGS='-I/d/Prog/winlibs64ucrt_stage/custombuilt/include/libdl-win32 -Wno-int-conversion' CXXFLAGS=-Wno-int-conversion LDFLAGS='-pthread -Wl,--dynamicbase -Wl,--high-entropy-va -Wl,--nxcompat -Wl,--tsaware' Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 12.2.0 (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) (base) PS C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin>常见问题安装其他内容nuitka main.py首次打包,看起来会有2-3次的报错,其实是在提示下载一些依赖,自动联网下载到c盘个人用户\appdata\local\nuitka下,主要下载MinGW和depends(Dependency Walker)和ccache,后面两个只有几M体积当然以上文件在国内大部分情况下直接下载都会是龟速或者直接下载报错,这里只需要在提示安装时选择yes,把下载地址和下载解压目录复制出来。科学上网手动下载对应文件并解压到命令行中提示的指定目录。depends.exe在第一次使用--standalone时,会提示安装Dependency Walker,nuitka需要使用这个工具来解析所有的依赖,从而决定拷贝哪些文件(dll,pyd)到exe目录。命令进行的过程中会自动检测该工具是否存在,没有的话会自动提示进行下载,网络没问题的时候直接回车或者输入yes就行了,但是如果网络状况不佳,就需要提前手动下载,否则命令会因此中断。具体步骤:手动下载和系统相匹配的版本(32位或64位),解压得到以下两个文件depends.exe depends.dll然后放置到对应的目录x86的路径C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\x86\X64的路径C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\x86_64\ps:我尝试过将工具放在path中,没有用,只能放在上面的路径里面可以通过参数 --windows-dependency-tool=DEPENDENCY_TOOL将其修改为其他依赖解析工具,比如pefile,但是不建议修改。参数 --windows-dependency-tool=DEPENDENCY_TOOL仅限windows系统使用三、Nuitka打包基础教程简单测试—不导入任何模块新建hello.pydef talk(message): return "Talk " + message先直接用python运行,看看有没有语法错误python hello.py然后进行打包构建nuitka hello.py命令结束后会生成一个exe,运行exe和执行上面第一条命令效果一样。复杂测试—导入其他模块为了测试模块引用,我们将上面的文件拆分成两部分新建mdl.pydef talk(message): return "Talk " + message修改hello.pyfrom mdl import talk def main(): print( talk("Hello World")) if __name__ == "__main__": main()先直接用python运行,看看有没有语法错误python hello.py然后进行构建nuitka hello.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.d ll保留了python的特性,比如调用一个python模块现在将整个目录拷贝到其他路径,可以发现exe能够正常执行,因为此时exe文件能够通过python3x.dll找到mdl.py。如果不想借助python3x.dll去调用模块,就要将这个模块打包进exenuitka --follow-import-to=mdl hello.py再次将生成的exe单独拷贝到其他地方执行,可以看到能够正常运行,此时不再需要拷贝python3x.dll和其他任何的文件。正式使用常用参数上面的测试过程,只是为了让你了解,默认的打包方式下,是需要注意依赖问题的,而我们一般都会打包成单文件形式。这里给出一个常用的打包方式,可以根据自己的需要进行修改:# windows下经常用的命令(单个文件+打包环境+关闭控制台+管理员权限+定义logo+清理过程文件+显示打包进度+显示内存占用+定义名称+定义版本+定义说明),注意最后的 main.py要根据实际情况修改 nuitka --onefile --standalone --windows-disable-console --windows-uac-admin --windows-icon-from-ico=我的logo.ico –remove-output --mingw64 --show-progress --show-memory --windows-product-name=上位机 --windows-product-version=1.0.0.2 --windows-file-description=一个软件的说明 out main.py GUI工具这种命令行参数,对于用户来说并不友好,所以有热心网友开发了GUI工具(html网页的形式),可以一键式配置,推荐使用:视频介绍:https://www.bilibili.com/video/BV1JEsTe3EC4/在线网站: nuitka-commander.github.io 项目主页: https://github.com/Nuitka-commander/nuitka-commander HTML下载: https://github.com/Nuitka-Commander/nuitka-commander.github.io/releases/latest 在线使用:https://nuitka-commander.github.io/此类GUI工具有挺多,例如还有:https://github.com/271374667/NuitkaGUI通用选项–-standalone 使得打包结果与本地的Python环境无关,可以发给没安装Python的电脑使用。–-onefile 使得打包结果为一个可执行的exe,而不是一个文件夹。--onefile选项下打出来的包本身就具备可移植性,因此不需要额外加上 --standalone。–-remove-output 在打包结束后,清理打包过程中生成的临时文件。–-enable-plugin= 启用插件,等号后跟插件名。在要打包的Python代码使用了一些特殊的包时,需要启用插件,Nuitka才能够正确打包。如:如在代码中使用了PySide6,就需要加上--enable-plugin=pyside6。具体的插件列表可以使用nuitka --plugin-list来查看。-–windows-disable-console 在运行打包后的程序时,不会弹出控制台,而是直接运行GUI程序。-–windows-icon-from-ico= 为打包后的可执行文件添加图标,等号后跟图标文件路径。值得注意的是,图标的格式也可以不是.ico,只需要安装过imageio包,Nuitka便可以自动将图片转换为.ico格式。修复选项打包程序往往并不是一次就能够打包成功的,常常会出现分析不出一部分的引用关系,忽略了一些数据文件等等情况。在这些情况下,我们需要根据运行程序后显示的报错信息,使用下面的选项来打出正确的包。–-include-package-data= 包含给定软件包名称中的数据文件,等号后软件包名称。有的时候Nuitka并不能正确分析出一些Python软件包所需要使用的数据文件,在运行程序时提示FileNotFoundError等错误,此时就需要使用该选项。如:--include-package-data=ultralytics–-include-data-files= 按文件名包含数据文件,等号后的格式为<SRC=DEST>。SRC指的是文件夹的路径,DEST指的是文件夹相对于打包结果的路径,其中DEST只能使用相对路径。如:--include-data-files=/Users/admin/Downloads/yolov5n.pt=./yolov5n.pt–-include-data-dir= 包含文件夹中的数据文件,等号后的格式为<SRC=DEST>。使用方法与--include-data-files=相同。其他选项参数--mingw64实际上 --mingw64与--msvc=MSVC是一对孪生参数,这两个参数二选一,用于指定编译器,如果当前环境既安装了mingw64,又安装了msvc,可以使用该参数选择兼容性最好的编译器,建议使用mingw64。如果不存在上面两种编译器都存在的情况,就不需要显式设置这个参数,默认会调用系统中能用的编译器。参数plugin control这部分参数用于设置对某些第三方库或者python功能进行支持,在使用--standalone时才会用到如果程序中使用了pyqt或者pyside,那么--plugin-enable=qt-plugins如果程序中使用了numpy, scipy, pandas, matplotlib,那么--plugin-enable=numpy如果使用了这些库或功能,但是忘了进行插件参数设置,命令运行过程中会以红字今天提醒,按照提醒对命令进行调整即可如果有多个插件需要启用--plugin-enable=numpy --plugin-enable=qt-plugins --plugin-enable=tensorflow①在使用pysimplegui(PySimpleGUI教程)时,需要在主代码中添加“import tkinter as tk”,并且设置--enable-plugins=tk-inter,这样可以让nuitka打包tkinter进你的代码中!②在使用pyside6/pyqt6(PySide6教程)时,需要设置--enable-plugins=pyside6或者pyqt6。可以使用 nuitka --plugin-list查看可用的插件C:\Users\Administrator\Desktop\a>nuitka --plugin-list The following optional standard plugins are available in Nuitka -------------------------------------------------------------------------------- data-files dill-compat enum-compat eventlet Required by the eventlet package gevent Required by the gevent package implicit-imports multiprocessing Required by Python's multiprocessing module numpy Required for numpy, scipy, pandas, matplotlib, etc. pbr-compat pmw-freezer Required by the Pmw package pylint-warnings Support PyLint / PyDev linting source markers qt-plugins Required by the PyQt and PySide packages tensorflow Required by the tensorflow package tk-inter Required by Python's Tk modules torch Required by the torch / torchvision packages参数Output choices-o FILENAME指定生成的可执行文件的文件名,但是生成pyd的时候无法使用,也就是在使用--module的时候无法为pyd文件指定一个其他的文件名--output-dir=DIRECTORY指定打包好的文件存放的目录,默认为当前目录--remove-output使用nuitka进行打包的过程中,会生成一个用于build的中间临时目录,若可以使用该参数,命令完成后会自动删除build目录--no-pyi-file不生成pyi文件。pyi文件主要用于生成pyd文件时进行隐式import的检测参数--show-progress 和--show-scons用来显示详细打包过程,看得懂的话就加上吧,这部分还有几个参数,感兴趣的可以试试 --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-disable-console禁用终端窗口,当程序有一个图形化界面的时候经常用到,仅限windows系统参数 --windows-icon=ICON_PATH设定程序的图标,仅限windows系统
2023年06月05日
106 阅读
6 评论
0 点赞
2023-05-07
python学习记录第25天
9.1 【调试技巧】超详细图文教你调试代码1. 调试的过程调试可以说是每个开发人员都必备一项技能,在日常开发和排查 bug 都非常有用。调试的过程分为三步:第一步:在你想要调试的地方,打上断点第二步:使用调试模式来运行这个 python 程序第三步:使用各种手段开始代码调试首先第一步和第二步,我用下面这张图表示点击上图中的小蜘蛛,开启调试模式后,在 PyCharm 下方会弹出一个选项卡。这个选项卡的按键非常多,包括变量查看窗口调试控制窗口线程控制窗口程序控制窗口在变量查看窗口,你可以查看当前程序进行到该断点处,所有的普通变量和特殊变量,你每往下执行一行代码,这些变量都有可能跟着改变。如果你的程序是多线程的,你可以通过线程控制窗口的下拉框来切换线程。以上两个窗口,都相对比较简单,我一笔带过,下面主要重点讲下调试控制按钮和程序控制按钮。在调试控制窗口,共有 8 个按钮,他们的作用分别是什么呢?Show Execution Point:无论你的代码编辑 窗口的光标在何处,只要点下该按钮,都会自动跳转到程序运行的地方。Step Over:在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。在不存在子函数的情况下是和step into效果一样的。简单的说就是,程序代码越过子函数,但子函数会执行,且不进入。Step Into:在单步执行时,遇到子函数就进入并且继续单步执行,有的会跳到源代码里面去执行。Step Into My Code:在单步执行时,遇到子函数就进入并且继续单步执行,不会进入到源码中。Step Out:假如进入了一个函数体中,你看了两行代码,不想看了,跳出当前函数体内,返回到调用此函数的地方,即使用此功能即可。Run To Cursor:运行到光标处,省得每次都要打一个断点。Evaluate Expression:计算表达式,在里面可以自己执行一些代码。以上七个功能,就是最常用的功能,一般操作步骤就是,设置好断点,debug运行,然后 F8 单步调试,遇到想进入的函数 F7 进去,想出来在 shift + F8,跳过不想看的地方,直接设置下一个断点,然后 F9 过去。看这张图就行了(下面第6点有误,应该是运行到光标处,而不是下一断点处)在程序控制窗口,共有 6 个按钮,他们的作用分别又是什么呢?同时看下面这张图就行了。2. 调试相关的快捷键⇧ + F9:调试当前文件⌥ + ⇧ + F9:弹出菜单,让你选择调试哪一个文件F8:单步执行,不进入函数F7:单步执行,进入函数⌥ + ⇧ +F7:单步执行,只进入自己写的函数⇧ + F8:跳出函数体F9:运行到下一断点⌥ + F9:运行到光标处⇧ + ⌘ + F8:查看所有设置的断点⌘ + F8:切换断点(有断点则取消断点,没有则加上断点)⌥ + F5:重新以调试模式运行⌥ + F8 计算表达式(可以更改变量值使其生效)
2023年05月07日
10 阅读
0 评论
1 点赞
2023-05-06
python学习记录第24天
8.1 【基础】什么是包、模块和库?Python 中除了函数库以外,还有非常多且优秀的第三方库、包、模块。那么问题就来了,库、模块和包各是什么意思?它们之间有什么区别呢?今天就一起来学习下。1. 模块以 .py 为后缀的文件,我们称之为 模块,英文名 Module。模块让你能够有逻辑地组织你的 Python 代码段,把相关的代码分配到一个模块里能让你的代码更好用,更易懂。假设现在有一个名为 demo.py 的文件,文件内容如下name="Python编程时光" print("导入成功")直接使用 import 语句就可以导入,导入之后,就可以使用 模块名.变量名 的方式访问这个变量。>>> import demo 导入成功 >>> demo.name 'Python编程时光' >>>在导入模块的时候,有一个非常重要的全局变量需要掌握,那就是 __name__ 这个变量。现在把 demo.py 的内容改成$ cat demo.py print("__name__ 的值为: " + __name__)当模块被直接执行时, __name__ 的值为 __main__$ python demo.py __name__ 的值为: __main__当模块被导入时, __name__ 的值为 模块名>>> import demo __name__ 的值为: demo当该模块被导入后,会在当前目录下产生一个 叫做 __pycache__ 的缓存文件夹。$ tree . ├── __pycache__ │ └── demo.cpython-39.pyc └── demo.py这个文件夹有什么用呢?简单来说,当你导入模块的时候,Python解释器会把模块的代码编译成字节码,并放入 __pycache__文件夹中。这样以后再次运行的话,如果被调用的模块未发生改变,那就直接跳过编译这一步,直接去__pycache__文件夹中去运行相关的 *.pyc 文件,大大缩短了项目运行前的准备时间。2. 包在早一点的 Python 版本(Python 3.3 之前)中,如果一个文件夹下有一个 __init__.py 文件,那我们就称之为包,英文名 Package。在后来的 Python 版本(Python 3.3 开始)中,就没有这个要求了,只要是文件夹就可以当做包,我们称之为空间命名包,为做区分,我把上面那种包称之为 传统包。今天这节里主要讲讲传统包的内容。传统包里的 __init__.py 可以为空文件,但一定要有该文件,它是包的标志性文件,在需要情况下可以在里面进行一些包的初始化工作。$ tree . └── demo ├── __init__.py ├── bar.py └── foo.py一个包里可以有多个模块,比如上面的 foo.py 和 bar.py 都属于 demo 模块。如果要使用这些模块,就需要这样导入>>> import demo.foo 成功导入 foo.py >>> import demo.bar 成功导入 bar.py或者这样>>> from demo import foo 成功导入 foo.py >>> from demo import bar 成功导入 bar.py3. 库Python 库是指一定功能的代码集合,通常认为他是一个完整的项目打包。库->包->模块,是从大到小的层级关系!库:一个库可能由多个包和模块组成包:一个包可能由多个模块组成模块:一堆函数、类、变量的集合8.2 【基础】安装第三方包的八种方法1. 使用 easy_installeasy_install 这应该是最古老的包安装方式了,目前基本没有人使用了。下面是 easy_install 的一些安装示例# 通过包名,从PyPI寻找最新版本,自动下载、编译、安装 $ easy_install pkg_name # 通过包名从指定下载页寻找链接来安装或升级包 $ easy_install -f http://pythonpaste.org/package_index.html # 指定线上的包地址安装 $ easy_install http://example.com/path/to/MyPackage-1.2.3.tgz # 从本地的 .egg 文件安装 $ easy_install xxx.egg2. 使用 pip installpip 是最主流的包管理方案,使用 pip install xxx 就可以从 PYPI 上搜索并安装 xxx (如果该包存在的话)。下面仅列出一些常用的 pip install 的安装示例$ pip install requests # 前提你得保证你已经下载 pkg 包到 /local/wheels 目录下 $ pip install --no-index --find-links=/local/wheels pkg # 所安装的包的版本为 2.1.2 $ pip install pkg==2.1.2 # 所安装的包必须大于等于 2.1.2 $ pip install pkg>=2.1.2 # 所安装的包必须小于等于 2.1.2 $ pip install pkg<=2.1.2更多 pip 的使用方法,可参考本系列教程后面的文章,介绍得非常清楚:8.8 pip 的详细使用指南3. 使用 pipxpipx 是一个专门用于安装和管理 cli 应用程序的工具,使用它安装的 Python 包会单独安装到一个全新的独有虚拟环境。由于它是一个第三方工具,因此在使用它之前,需要先安装$ python3 -m pip install --user pipx $ python3 -m userpath append ~/.local/bin Success!安装就可以使用 pipx 安装cli 工具了。# 创建虚拟环境并安装包 $ pipx install pkg更多 pipx 的使用方法,可参考本系列教程后面的文章,介绍得非常清楚:12.4 pipx 安装程序的使用指南4. 使用 setup.py如果你有编写 setup.py 文件,可以使用如下命令直接安装# 使用源码直接安装 $ python setup.py install5. 使用 yumPython 包在使用 setup.py 构建的时候(具体内容可阅读后面的内容:8.15 超详细讲解 setup.py 的编写),对于包的发布格式有多种选项,其中有一个选项是 bdist_rpm,以这个选项发布出来的包是 rpm 的包格式。# 发布 rpm 包 $ python setup.py bdist_rpm对于rpm 这种格式,你需要使用 yum install xxx 或者 rpm install xxx 来安装。# 使用 yum 安装 $ yum install pkg # 使用 rpm 安装 $ rpm -ivh pkg6. 使用 pipenv如果你在使用 pipenv 创建的虚拟环境中,可以使用下面这条命令把包安装到虚拟环境中$ pipenv install pkg7. 使用 poetry如果你有使用 poetry 管理项目依赖,那么可以使用下面这条命令安装包# 直接安装包 $ poetry add pkg # 指定为开发依赖 $ poetry add pytest --dev8. 使用 curl + 管道有一些第三方工具包提供的安装方法,是直接使用 curl 配置管道来安装,比如上面提到的 poetry 就可以用这种方法安装。$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python'''1、导入包&使用的基本语法 导入:import 包名.模块 使用:包名.模块.功能 from 包名 import 模块 在使用时 模块.功能, 不用带包名'''导入包下的模块import bao.module01bao.module01.hi()from bao import module02module02.ok()'''2、导入包的模块的指定函数、类、变量 from 包名.模块 import 函数、类、变量 在使用时,直接调用功能from 包名.模块 import * :表示导入包的模块的所有功能'''from bao.module01 import hihi()from bao.module02 import *ok()'''3、__init__.py 通过__all__控制允许导入的模块 1、在__init__.py 中增加__all__ = [允许导入的模块列表] 2、针对 from 包 import * 方式生效,对 import xx 方式不生效'''from bao import *hi()ok()'''4、快速导入模块的快捷键 1、alt + enter , 提示你选择解决方案 2、 alt +shift +enter , 直接导入'''
2023年05月06日
4 阅读
0 评论
1 点赞
1
2
...
6