python打包可执行文件详解(pyinstaller)

python打包可执行文件详解(pyinstaller)

  • 基本使用
  • 常用参数及使用
      • 单个文件打包 -F
      • 隐藏命令行运行窗口 -w
      • 设置图标 -i
  • 全部参数及使用
    • 常规选项 optional arguments
      • 帮助 -h / --help
      • 版本 -v / --version
      • 设置exe生成位置 --distpath
      • 设置中间文件位置 --workpath
      • 询问dist覆盖意见 -y / --noconfirm
      • 压缩文件 --upx-dir
      • 编码模式 -a / --ascii
      • 删除缓存 --clean
      • 打包显示信息量 --log-level
    • 产生什么 What to generate
      • 分散打包 -D/--onedir
      • 单个文件 -F/--onefile
      • 规范文件位置 --spacepath
      • 改名 -n/--name
    • 捆绑与搜索的地址 What to bundle, where to search
    • 怎样生成 How to generate
  • 关于我在打包过程中遇到的问题
    • 找不到nltk_data的位置
    • 打包后的exe报错找不到模组
    • 打包时提示超过最大递归层数
    • 编码错误
    • 打包出来的文件巨大
  • 帮助信息 -h/--help

基本使用

安装pyinstaller

pip install pyinstaller


命令行到达.py文件位置

cd D:\code


把zzz.py打包成exe文件(非独立)

pyinstaller zzz.py

完成后生成三个文件夹“__pycache__”(缓存)、“build”(临时文件)、“dist”(生成文件)和 一个文件“zzz.spec”(配置文件)
默认-D模式打成文件夹
打完包的exe在名为"dist"文件夹下的“zzz”文件夹内,如果要给别人用,需要把整个"zzz"文件夹都打包送走

常用参数及使用

单个文件打包 -F

pyinstaller -F zzz.py

打完包的exe在"dist"文件夹下,可以直接运行

隐藏命令行运行窗口 -w

隐藏黑框框

pyinstaller -w zzz.py

如果写了类似system pause之类的,那么还是会出现命令行告诉你按任意键结束

和-F一起使用风味更佳

pyinstaller -F -w zzz.py

设置图标 -i

-i后面一个空格加图片地址,建议放在同一文件夹下,比较方便打个文件名就行了

pyinstaller -F -i pic.ico zzz.py

如果发现生成的exe图标还是黑蓝黄白的方框小蟒蛇,可以把exe复制黏贴一次,图标就神奇的出现了

全部参数及使用

按照帮助信息顺序尝试后得出
因为太麻烦,不包含任何需要其他程序辅助的功能,比如upx压缩功能之类的,但是提供翻译

常规选项 optional arguments

帮助 -h / --help

显示pyinstaller的帮助信息,我复制下来放在最后一个大标题了

版本 -v / --version

显示pyinstaller的版本
任何的pyinstaller加上它,都只显示版本信息
比如下面这几条,只显示版本信息

pyinstaller -F -i pic.ico -v zzz.py
pyinstaller 6666-F -v 1.1.2 zzz.py 23333333333333

设置exe生成位置 --distpath

更改exe生成的位置
这里我改成在当前文件夹下的”anotherpath“文件夹来存放生成的exe

pyinstaller -F -i icon04.ico --distpath .\anotherpath zzz.py

设置中间文件位置 --workpath

pyinstaller也不是直接一步到位打包完的,有许多中间文件,之前是放在“build”文件夹下,现在你可以设置它的位置
这里我改成放在“anotheranotherpath”文件夹里

pyinstaller -F -i icon04.ico --workpath .\anotheranotherpath zzz.py

询问dist覆盖意见 -y / --noconfirm

如果你的exe生成位置已经存在东西,那么在打包过程中会问你这么一句话(在-F条件下不会问这个问题)

WARNING: The output directory “D:\Code\dist\zzz” and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)

大意是文件夹里已经有东西了,要不要覆盖他们呢?
如果加了-y那么该情况下就不会问这个问题,直接覆盖,比如下面这样

pyinstaller -y zzz.py

压缩文件 --upx-dir

用upx压缩可执行文件,生成文件会比不压缩的要小
没试过

pyinstaller -F --upx-dir UPX_DIR zzz.py

编码模式 -a / --ascii

不支持unicode编码
没试出来加不加有什么区别,可能自动优化了?
留个空______________

删除缓存 --clean

删除pyinstaller的缓存和之前的临时文件
假如依次执行一下三条

pyinstaller -F zzz.py
pyinstaller -F zzz.py
pyinstaller -F --clean zzz.py

你会发现第二条非常快,因为它直接使用了第一条运行时产生的临时文件,而第三条和第一条的执行速度差不多,因为第三条将临时文件删除,自己重新再产生了,从执行时的信息也能看出,一三两条明显步骤更多

打包显示信息量 --log-level

控制打包时控制台的详细信息量
在你的程序打包时出错,然后消息太多,找不到报错提示的时候比较有用

pyinstaller -F --clean --log-level LEVEL zzz.py

LEVEL的取值为(DEBUG,INFO,WARN,ERROR,CRITICAL(默认值:INFO))
DEBUG会比INFO多更多的调试信息
WARN只显示警告信息
ERROR只显示错误信息
CRITICAL这个我还没遇到过,紧急信息?留个空______________

产生什么 What to generate

分散打包 -D/–onedir

前面提过,就默认的模式

单个文件 -F/–onefile

前面提过,打成单个文件

规范文件位置 --spacepath

设置用于存储生成的规范文件(就是py文件同目录下的.spec文件,主要存储打包的设置)的文件夹
比如我这么写,.spec文件就会存储到同目录下的aaa文件夹下

pyinstaller -F --clean --specpath aaa zzz.py

改名 -n/–name

修改可执行文件的名字(默认是.py文件的名字)
比如

pyinstaller -F --clean -n hhh zzz.py

那么build和dist文件夹下zzz的位置都会变成hhh,但是缓存文件的名字(__pycache__文件夹下)不会变

捆绑与搜索的地址 What to bundle, where to search

主要是用于打包的时候找不到库

怎样生成 How to generate

关于我在打包过程中遇到的问题

找不到nltk_data的位置

报错是

Unable to find “C:\nltk_data” when adding binary and data files

一开始我真的以为他提示的地方必须有nltkdata,就傻乎乎把所有报错的位置都粘了一份nltk_data,直到第六个我才发现不对劲啊
解决方法
在你的pyinstaller安装目录(比如:D:\Anaconda\Lib\site-packages\PyInstaller\hooks)下找到一个叫“hook-nltk.py”的文件,打开更改

# loop through the data directories and add them
for p in nltk.data.path:
datas.append((p, “nltk_data”))

# loop through the data directories and add them
datas.append((“NLTK_DATA_PATH”, “nltk_data”))

NLTK_DATA_PATH是你存放nltk_data的位置(比如:D:\Anaconda\Lib\site-packages\nltk\nltk_data)

打包后的exe报错找不到模组

报错信息是

ModuleNotFoundError: No module named ‘pkg_resources.py2_warn’

因为我打包的程序运行时间比较长,所以一开始一直没看到报错信息,就知道过了很久莫名其妙闪退了,但是在编译器里运行一切正常
解决办法
这里推荐开另外一个命令行来运行exe,这样就不会闪退看不到报错
(曾经我也是会拍视频来捕捉闪退的傻孩子啊)
(ps:如果时通过os.path读取文件的,要先把另一个命令行的位置cd到程序所在的地址,不然os.path读取的会是那个命令行的位置,VSCode的控制台也是)
打开.spec文件,修改

hiddenimports=[],

hiddenimports=[‘MODULE_NAME’],

MODULE_NAME填你缺失的模组名,缺失很多模组那么就逗号隔开

打包时提示超过最大递归层数

原因大概是用的一个库自己循环、递归太多了,超过python的默认栈深度,一般在IDE里运行没事儿,打包的时候会出错
报错信息是

RecursionError: maximum recursion depth exceeded while calling a Python object

解决办法
打开.spec文件,在

# -*- mode: python ; coding: utf-8 -*-

的下一行,添加

import sys
sys.setrecursionlimit(1000000000)

意思是设置最大递归深度为1000000000,这个数字随你设置,稍微大一点就行,默认大小是1000
这两行直接加载代码里会让运行速度变快,类似于电脑增加了内存的感觉
但是加载代码里并不会在打包的时候生效,照样报错,所以一定要加载打包的配置文件里。

编码错误

错误提示

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in position 109: invalid continuation byte

解决方法
修改pyinstaller安装目录下的compat.py文件(这个文件的内容是处理各种兼容问题的,比如python2和python3的不同之类的,所以啥小事都要管)中的

out = out.decode(encoding)

out = out.decode(encoding, errors=‘ignore’)

python打包可执行文件详解(pyinstaller)_第1张图片
向我一样用Anaconda的话,这个目录在

D:\Anaconda\Lib\site-packages\PyInstaller

找不到的话在努力找找吧,或者下一个Everything查一下

打包出来的文件巨大

打包出来的文件巨大,动不动几个G
我自己不习惯开一个项目就建立一个新的虚拟环境,一直都在用一个什么都有的环境,而pyinstaller会把他能拿到的各种杂七杂八的东西抓过来

解决方法
建立新的虚拟环境,只安装该项目必须的库

帮助信息 -h/–help

usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]
                   [--add-data ]
                   [--add-binary ] [-p DIR]
                   [--hidden-import MODULENAME]
                   [--additional-hooks-dir HOOKSPATH]
                   [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
                   [--key KEY] [-d {all,imports,bootloader,noarchive}] [-s]
                   [--noupx] [--upx-exclude FILE] [-c] [-w]
                   [-i ]
                   [--version-file FILE] [-m ] [-r RESOURCE]
                   [--uac-admin] [--uac-uiaccess] [--win-private-assemblies]
                   [--win-no-prefer-redirects]
                   [--osx-bundle-identifier BUNDLE_IDENTIFIER]
                   [--runtime-tmpdir PATH] [--bootloader-ignore-signals]
                   [--distpath DIR] [--workpath WORKPATH] [-y]
                   [--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL]
                   scriptname [scriptname ...]

positional arguments:
  scriptname            name of scriptfiles to be processed or exactly one
                        .spec-file. If a .spec-file is specified, most options
                        are unnecessary and are ignored.

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         Show program version info and exit.
  --distpath DIR        Where to put the bundled app (default: .\dist)
  --workpath WORKPATH   Where to put all the temporary work files, .log, .pyz
                        and etc. (default: .\build)
  -y, --noconfirm       Replace output directory (default:
                        SPECPATH\dist\SPECNAME) without asking for
                        confirmation
  --upx-dir UPX_DIR     Path to UPX utility (default: search the execution
                        path)
  -a, --ascii           Do not include unicode encoding support (default:
                        included if available)
  --clean               Clean PyInstaller cache and remove temporary files
                        before building.
  --log-level LEVEL     Amount of detail in build-time console messages. LEVEL
                        may be one of TRACE, DEBUG, INFO, WARN, ERROR,
                        CRITICAL (default: INFO).

What to generate:
  -D, --onedir          Create a one-folder bundle containing an executable
                        (default)
  -F, --onefile         Create a one-file bundled executable.
  --specpath DIR        Folder to store the generated spec file (default:
                        current directory)
  -n NAME, --name NAME  Name to assign to the bundled app and spec file
                        (default: first script's basename)

What to bundle, where to search:
  --add-data 
                        Additional non-binary files or folders to be added to
                        the executable. The path separator is platform
                        specific, ``os.pathsep`` (which is ``;`` on Windows
                        and ``:`` on most unix systems) is used. This option
                        can be used multiple times.
  --add-binary 
                        Additional binary files to be added to the executable.
                        See the ``--add-data`` option for more details. This
                        option can be used multiple times.
  -p DIR, --paths DIR   A path to search for imports (like using PYTHONPATH).
                        Multiple paths are allowed, separated by ';', or use
                        this option multiple times
  --hidden-import MODULENAME, --hiddenimport MODULENAME
                        Name an import not visible in the code of the
                        script(s). This option can be used multiple times.
  --additional-hooks-dir HOOKSPATH
                        An additional path to search for hooks. This option
                        can be used multiple times.
  --runtime-hook RUNTIME_HOOKS
                        Path to a custom runtime hook file. A runtime hook is
                        code that is bundled with the executable and is
                        executed before any other code or module to set up
                        special features of the runtime environment. This
                        option can be used multiple times.
  --exclude-module EXCLUDES
                        Optional module or package (the Python name, not the
                        path name) that will be ignored (as though it was not
                        found). This option can be used multiple times.
  --key KEY             The key used to encrypt Python bytecode.

How to generate:
  -d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive}
                        Provide assistance with debugging a frozen
                        application. This argument may be provided multiple
                        times to select several of the following options.

                        - all: All three of the following options.

                        - imports: specify the -v option to the underlying
                          Python interpreter, causing it to print a message
                          each time a module is initialized, showing the
                          place (filename or built-in module) from which it
                          is loaded. See
                          https://docs.python.org/3/using/cmdline.html#id4.

                        - bootloader: tell the bootloader to issue progress
                          messages while initializing and starting the
                          bundled app. Used to diagnose problems with
                          missing imports.

                        - noarchive: instead of storing all frozen Python
                          source files as an archive inside the resulting
                          executable, store them as files in the resulting
                          output directory.

  -s, --strip           Apply a symbol-table strip to the executable and
                        shared libs (not recommended for Windows)
  --noupx               Do not use UPX even if it is available (works
                        differently between Windows and *nix)
  --upx-exclude FILE    Prevent a binary from being compressed when using upx.
                        This is typically used if upx corrupts certain
                        binaries during compression. FILE is the filename of
                        the binary without path. This option can be used
                        multiple times.

Windows and Mac OS X specific options:
  -c, --console, --nowindowed
                        Open a console window for standard i/o (default). On
                        Windows this option will have no effect if the first
                        script is a '.pyw' file.
  -w, --windowed, --noconsole
                        Windows and Mac OS X: do not provide a console window
                        for standard i/o. On Mac OS X this also triggers
                        building an OS X .app bundle. On Windows this option
                        will be set if the first script is a '.pyw' file. This
                        option is ignored in *NIX systems.
  -i , --icon 
                        FILE.ico: apply that icon to a Windows executable.
                        FILE.exe,ID, extract the icon with ID from an exe.
                        FILE.icns: apply the icon to the .app bundle on Mac OS
                        X

Windows specific options:
  --version-file FILE   add a version resource from FILE to the exe
  -m , --manifest 
                        add manifest FILE or XML to the exe
  -r RESOURCE, --resource RESOURCE
                        Add or update a resource to a Windows executable. The
                        RESOURCE is one to four items,
                        FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file
                        or an exe/dll. For data files, at least TYPE and NAME
                        must be specified. LANGUAGE defaults to 0 or may be
                        specified as wildcard * to update all resources of the
                        given TYPE and NAME. For exe/dll files, all resources
                        from FILE will be added/updated to the final
                        executable if TYPE, NAME and LANGUAGE are omitted or
                        specified as wildcard *.This option can be used
                        multiple times.
  --uac-admin           Using this option creates a Manifest which will
                        request elevation upon application restart.
  --uac-uiaccess        Using this option allows an elevated application to
                        work with Remote Desktop.

Windows Side-by-side Assembly searching options (advanced):
  --win-private-assemblies
                        Any Shared Assemblies bundled into the application
                        will be changed into Private Assemblies. This means
                        the exact versions of these assemblies will always be
                        used, and any newer versions installed on user
                        machines at the system level will be ignored.
  --win-no-prefer-redirects
                        While searching for Shared or Private Assemblies to
                        bundle into the application, PyInstaller will prefer
                        not to follow policies that redirect to newer
                        versions, and will try to bundle the exact versions of
                        the assembly.

Mac OS X specific options:
  --osx-bundle-identifier BUNDLE_IDENTIFIER
                        Mac OS X .app bundle identifier is used as the default
                        unique program name for code signing purposes. The
                        usual form is a hierarchical name in reverse DNS
                        notation. For example:
                        com.mycompany.department.appname (default: first
                        script's basename)

Rarely used special options:
  --runtime-tmpdir PATH
                        Where to extract libraries and support files in
                        `onefile`-mode. If this option is given, the
                        bootloader will ignore any temp-folder location
                        defined by the run-time OS. The ``_MEIxxxxxx``-folder
                        will be created here. Please use this option only if
                        you know what you are doing.
  --bootloader-ignore-signals
                        Tell the bootloader to ignore signals rather than
                        forwarding them to the child process. Useful in
                        situations where e.g. a supervisor process signals
                        both the bootloader and child (e.g. via a process
                        group) to avoid signalling the child twice.

持续更新。。。

你可能感兴趣的:(python)