关于pyinstaller 打包多个py文件的问题

目录
  • 安装pyinstall
  • 注意事项
  • 参数详解
  • pyinstaller最佳使用方式
    • 第一步,通过上面的命令执行打包,此时会生成相应的spec文件
    • 第二步:对xxx.spec文件执行pyinstaller 指令
  • spec文件解析
    • 手动修改spec文件
  • 笔记: pyinstaller的常见问题
    • 尝试解决1:
    • 尝试解决1,测试结果:
  • 以下上是给我启发的网友的操作方式,记录并感谢
    • 实验项目结构
  • 遇到的问题
  • Python 中的 exit() 和 sys.exit() 的区别

安装pyinstall

pip install pyinstaller

注意事项

除非必要,否则尽量不要直接import module,用from xxx import xxx来代替,减少打包需要加载的模块,

缩减最终的exe体积

参数详解

usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]
                   [--add-data <SRC;DEST or SRC:DEST>]
                   [--add-binary <SRC;DEST or SRC:DEST>] [-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 <FILE.ico or FILE.exe,ID or FILE.icns>]
                   [--version-file FILE] [-m <FILE or XML>] [-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    
    要处理的脚本文件的名称或正好一个.spec文件。 如果指定了.spec文件,则大多数选项是不必要的,将被忽略。

可选参数:
  -h,--help显示此帮助消息并退出
  -v,--version显示程序版本信息并退出。
  --distpath DIR放置捆绑的应用程序的位置(默认值:。\ dist)
  --workpath WORKPATH将所有临时工作文件,.log,.pyz放在哪里
                        等(默认值:。\ build)
  -y,--noconfirm替换输出目录(默认值:
                        SPECPATH \ dist \ SPECNAME)而不要求
                        确认
  --upx-dir UPX_DIR UPX实用程序的路径(默认值:搜索执行)
                        路径)
  -a,-ascii不包括unicode编码支持(默认值:
                        包括(如果有)
  --clean清理PyInstaller缓存并删除临时文件
                        在建造之前。
  --log-level LEVEL生成时控制台消息中的详细信息量。水平
                        可能是TRACE,DEBUG,INFO,WARN,ERROR,
                        严重(默认:INFO)。

产生什么:
  -D,--onedir创建一个包含可执行文件的单文件夹捆绑包
                        (默认)
  -F,--onefile创建一个文件捆绑的可执行文件。
  --specpath DIR文件夹,用于存储生成的规范文件(默认值:
                        当前目录)
  -n NAME,--name NAME分配给捆绑的应用程序和规范文件的名称
                        (默认值:第一个脚本的基本名称)

捆绑内容,搜索位置:
  --add-data <SRC; DEST或SRC:DEST>
                        要添加到的其他非二进制文件或文件夹
                        可执行文件。路径分隔符是平台
                        特定的`os.pathsep``(在Windows上是``;``
                        和``:``在大多数Unix系统上)。这个选项
                        可以多次使用。
  --add-binary <SRC; DEST或SRC:DEST>
                        要添加到可执行文件的其他二进制文件。
                        有关更多详细信息,请参见--add-data选项。这个
                        该选项可以多次使用。
  -p DIR,--paths DIR搜索导入的路径(例如使用PYTHONPATH)。
                        允许使用多个路径,以“;”分隔,或使用
                        此选项多次
  --hidden-import MODULENAME,-hiddenimport MODULENAME
                        命名在代码中不可见的导入
                        脚本。此选项可以多次使用。
  --additional-hooks-dir HOOKSPATH
                        搜索钩子的其他路径。这个选项
                        可以多次使用。
  --runtime-hook RUNTIME_HOOKS
                        定制运行时挂钩文件的路径。运行时挂钩是
                        与可执行文件捆绑在一起的代码是
                        在设置任何其他代码或模块之前执行
                        运行时环境的特殊功能。这个
                        该选项可以多次使用。
  --exclude-module排除
                        可选模块或软件包(Python名称,而不是
                        路径名称)将被忽略(好像不是)
                        找到)。此选项可以多次使用。
  --key KEY用于加密Python字节码的密钥。

如何产生:
  -d {all,imports,bootloader,noarchive},--debug {all,imports,bootloader,noarchive}
                        提供调试冻结的协助
                        应用。可以多次提供此参数
                        选择以下几个选项的时间。
                        
                        -全部:以下所有三个选项。
                        
                        -导入:为基础指定-v选项
                          Python解释器,导致其打印消息
                          每次模块初始化时,显示
                          来源(文件名或内置模块)
                          已加载。看到
                          https://docs.python.org/3/using/cmdline.html#id4。
                        
                        -自举程序:告诉自举程序发出进度
                          初始化并启动
                          捆绑的应用。用于诊断问题
                          缺少进口。
                        
                        -存档:而不是存储所有冻结的Python
                          源文件作为结果中的存档
                          可执行文件,将它们存储为文件
                          输出目录。
                        
  -s,--strip将符号表条应用于可执行文件并
                        共享库

pyinstaller最佳使用方式

常用的命令为

pyinstall -i xxx.ico -n xxx -w -D main.py

其中 -D 参数或 -F 参数后面跟的是入口文件,即你 python xxx.py 运行程序时这个xxx.py文件

对应依赖比较多的程序,建议使用 -D, -F更适合单文件的py脚本。

pyinstaller 打包其实分两步走

第一步,通过上面的命令执行打包,此时会生成相应的spec文件

大体流程如下:

1、在脚本目录生成 xxx.spec 文件(看-n参数,没传,则与xxx.py同名为xxx); 
2、创建一个 build 目录; 
3、写入一些日志文件和中间流程文件到 build 目录; 
4、创建 dist 目录; 
5、生成可执行文件或文件夹到 dist 目录;

效果如下:

第一步完成后,获得xxx.spec,然后再执行

第二步:对xxx.spec文件执行pyinstaller 指令

pyinstaller xxx.spec

完成打包

进入dist中打包好的文件夹后,双脚运行可执行文件则可
这是一个利用tkinter构建界面的简单程序

spec文件解析

一个spec文件的例子。

block_cipher =None
a =Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
ciper=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,...)
coll = COLLECT(...)

spec文件中主要包含4个class: Analysis, PYZ, EXE 和 COLLECT.

  • Analysis以py文件为输入,它会分析py文件的依赖模块,并生成相应的信息
  • PYZ是一个.pyz的压缩包,包含程序运行需要的所有依赖
  • EXE根据上面两项生成
  • COLLECT生成其他部分的输出文件夹,COLLECT也可以没有

手动修改spec文件

有时候PyInstaller自动生成的spec文件并不能满足我们的需求,最常见的情况就是我们的程序依赖我们本地的一些数据文件,这个时候就需要我们自己去编辑spec文件来添加数据文件了。 上面的spec文件解析中Analysis中的datas就是要添加到项目中的数据文件,我们可以编辑datas.

a =Analysis(
...
datas =[('you/source/file/path','file_name_in_project'),
('source/file2','file_name2')]
...
)

可以认为datas是一个List,每个元素是一个二元组。元组的第一个元素是你本地文件索引,第二个元素是拷贝到项目中之后的文件名字。除了上面那种写法,也可以将其提出来。

added_files =[...]
a =Analysis(
...
datas = added_files,
...
)

笔记: pyinstaller的常见问题

到此为止pyinstaller的知识已经大致了解,但是并没有解决是实操时, 主py文件调用其他py文件(自定义的)时,无法找到该模块的问题。如下图:

尝试解决1:

根据下面网友经验,在spec文件中加入根目录:

...
a = Analysis(['test1.py'],
             pathex=['D:\Python_X64\dynamic_positioning'],   # 加入根目录,且text2.py也在该目录中
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
...

尝试解决1,测试结果:

记过如上修改,问题重要解决。程序不再报错,并且正常运行。

以下上是给我启发的网友的操作方式,记录并感谢

实验项目结构

在sampleproject目录下执行tree /f 查看文件结构

pyinstaller -F  -c simple.py -p __init__.py -p test_install.py

打包多个py文件的命令

pyinstaller [主文件] -p [其他文件1] -p [其他文件2] --hidden-import [自建模块1] --hidden-import [自建模块2] 

其中sample.py是主程序入口文件,其他.py文件是自建模块(test_install.py)。所以在执行下面命令:

pyinstaller -F -c simple.py -p __init__.py -p test_install.py

执行完成后会产生2个文件夹build,dist和一个文件simple.spec

进入exe目录并成功执行exe程序

OK 这样就完成了打包的程序,事实上,我并不是这么顺利,中间也遇到些问题

遇到的问题

Failed to execute script ‘simple’ due to unhandled exception!

首先看下py文件的内容,内容瞎写的,只是为了测试!!!

test_install.py 文件
def install_test():
    print('install test!')

simple.py 调用 test_install.py 中的方法

注意:方法1和方法2 的区别在于 导入模块的方式

  • simple.py 文件

方式一

import test_install    # import xxx 导入方式
...
test_install.install_test()

- 方式二

 from test_install import install_test   # from xxx import xxx 导入方式
 ...
 install_test()

这2种方式用python simple.py 都是能通过的,然而方式一和方式二打包后都有报错ModuleNotFoundError: No module named ‘test_install’
[37320] Failed to execute script ‘simple’ due to unhandled exception!

笔记:我显示的报错和这位网友并不相同。显示内容如下:

解决方法:
原因 install_test 是在sample包下,导入路径要写上父包的路径

方式三

from sample.test_install import install_test   # 增加了sample,但是,我的sample为项目目录,pycharm会报错的
...
install_test()

方式四

from sample import test_install                # 这种写法比较有趣,由于我的sample为项目目录,pycharm会报错的
...
test_install.install_test()

笔记:由于项目目录的原因,方式3和方式4我的测试并不成功。也许不是项目目录应该可以解决。与我的解决思路感觉是一致的。

遇到的问题

NameError: name ‘exit’ is not defined

解决方法:在simple.py中使用的exit()替换为sys.exit()

出错的原因exit 用于给交互式 Shell 返回值,而 sys.exit 是用于程序内部

Python 中的 exit() 和 sys.exit() 的区别

exit is a helper for the interactive shell - sys.exit is intended for use in programs.

The site module (which is imported automatically during startup, except if the -S command-line option is given) adds several constants to the built-in namespace (e.g. exit). They are useful for the interactive interpreter shell and should not be used in programs.

Note that there is a third exit option, namely os._exit, which exits without calling cleanup handlers, flushing stdio buffers, etc. (and which should normally only be used in the child process after a fork()).

对于上面的引用的理解:

exit()/quit(), 抛出 SystemExit 异常. 一般在交互式 Shell 中退出时使用.
sys.exit(n) 退出程序引发 SystemExit 异常, 可以捕获异常执行些清理工作. n 默认值为 0, 表示正常退出. 其他都是非正常退出. 还可以 sys.exit(“sorry, goodbye!”); 一般主程序中使用此退出.
os._exit(n), 直接退出, 不抛异常, 不执行相关清理工作. 常用在子进程的退出.

到此这篇关于pyinstaller 打包多个py文件的文章就介绍到这了,更多相关pyinstaller 打包py文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 利用pyinstaller将py文件打包为exe的方法

    写在前面 做大创的时候,因为需要计算合金的各种能量.温度等一大堆数据,为了能够福泽后来的学弟学妹,我决定将我处理数据时用的python程序打包成exe,这样就可以在没有安装python环境的电脑上运行我的程序了.所以上网查了一大堆如何打包的方法,尝试了py2exe和pyinstaller这两种方法,发现还是后者更加的简单便捷.同时为了能够帮助我自己以后再想用到的时候有一个教程可以查找,我就写了这一篇博客出来,留作纪念. 前提条件 首先我们需要两个东西:python3.4版本,pyinstalle

  • pyinstaller打包多个py文件和去除cmd黑框的方法

    1.打包多个py文件并且去除cmd黑框 格式:pyinstaller.exe -F 路径\文件名.py空格路径\文件名.py空格--noconsole 以上这篇pyinstaller打包多个py文件和去除cmd黑框的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • python非单一.py文件用Pyinstaller打包发布成exe

    目录 一:背景以及项目结构介绍 二:实施步骤 1:总体思路 2:安装pyinstaller 3:具体步骤(以我项目为例子) 三:疑难杂症和需要注意的坑 1:打包找不到模块问题 2:打包后,一直提示Failed to execute scrpt xxx问题 3:cmd下运行打包好的exe,运行一段时间卡主不动,按一下回车才继续 4:其他注意事项 一:背景以及项目结构介绍 第一次将自己做的python爬虫项目打包成exe,搜了很多网上教程,大部分都是打包一个py文件的小demo,这里先给个笑脸吧,除

  • 关于pyinstaller 打包多个py文件的问题

    目录 安装pyinstall 注意事项 参数详解 pyinstaller最佳使用方式 第一步,通过上面的命令执行打包,此时会生成相应的spec文件 第二步:对xxx.spec文件执行pyinstaller 指令 spec文件解析 手动修改spec文件 笔记: pyinstaller的常见问题 尝试解决1: 尝试解决1,测试结果: 以下上是给我启发的网友的操作方式,记录并感谢 实验项目结构 遇到的问题 Python 中的 exit() 和 sys.exit() 的区别 安装pyinstall pi

  • 如何对Python编译PyInstaller打包生成的exe文件进行反编译生成pyc、py源代码文件

    目录 准备工作 根据exe生成pyc文件 根据pyc文件反编译为py文件 参考 总结 准备工作 没有加壳的python编译并打包的exe文件 python反打包代码(不知道这样叫是否合理):python-exe-unpacker 16进制编辑查看器 :Hex Editor Neo 反编译库 :uncompyle6 根据exe生成pyc文件 下载并解压缩 python-exe-unpacker 代码,myfile.exe为需要反编译的exe文件 使用python运行 python-exe-unpa

  • pyinstaller打包找不到文件的问题解决

    1.将python程序打包成单文件(使用 -F 参数)后,尝试运行外部文件却提示找不到的问题 当你将python程序打包成单文件(使用 -F 参数)后,运行程序,它实际上是先将exe内的资源文件解压到临时文件夹,然后再运行的,所以会导致这种问题 比如,当你在程序里面调用一个外部exe时,但却提示找不到该exe文件. 例子(这里我用win32api去隐式运行外部exe文件): import win32api win32api.ShellExecute(0, 'open', 'nginx.exe',

  • 使用pyinstaller打包.exe文件的详细教程

    为什么要打包? 1:当你想把你做的python游戏或者是脚本等.py文件发给别人时,打包为.exe文件,即使对方没有安装python也能运行 2:单纯想秀一下hhh 安装pyinstaller 安装pyinstaller很简单,直接cmd使用pip命令即可 pip install pyinstaller pyinstaller打包单个.py文件步骤 使用之前做的时钟为例进行演示 1:单击以下区域输入cmd切换到目标文件目录 2:输入pyinstaller -F -w Analog_clock.p

  • 如何使用pyinstaller打包多个和单个python文件详解

    目录 一.打包多个 二.打包单个文件 总结 一.打包多个 1.将需要打包的项目为anjuke_sd目录下的所有python文件,其中excute_main.py为主文件. 2.生成主函数对应的spec文件 命令:在anjuke_sd路径下使用:pyi-makespec excute_main.py 如下图已经生成excute_main.spec文件. 3.修改spec文件:加入需要打包的所有python文件,同时确保以下两项包含该项目的路径 4.对spec文件进行pyinstaller安装 命令

  • 简单介绍一下pyinstaller打包以及安全性的实现

    pyinstaller打包问题 简单介绍一下pyinstaller常用的参数: 可选参数 示例 说明 -F pyinstaller -F demo.py 只在dist文件夹中生成一个程序demo.exe文件,适用于一个模块没有多依赖.py文件 -D pyinstaller -D demo.py 默认选项,除了主程序demo.exe外,还会在在dist文件夹中生成很多依赖文件,推荐使用这个 -c pyinstaller -c demo.py 默认选项,只对windows有效,使用控制台 -w py

  • pyinstaller打包可执行文件,存放路径包含中文无法运行的解决方案

    一.实验环境 1.Windows7x64_SP1 2.anaconda2.5.0 + python2.7(anaconda集成,不需单独安装) 3.pyinstaller3.0 二.问题描述 1.使用如上环境,pyinstaller打包生成的exe文件,存放在本地,如果路径中包含中文,程序无法运行:exe程序如果使用中文命名,程序同样无法运行. 三.解决方式 1.查看pyinstaller网站 https://pypi.org/project/PyInstaller/ 2.有如下描述 3.更换实

随机推荐