• python-55-打包exe执行


    前言

    你是否有这种烦恼?

    • 他人在使用你的项目、工具时可能只需关注使用,但还需要安装各种依赖包?
    • 共用服务机器环境,偶尔被他人改了依赖包版本,导致运行不起来?
    • 换台机器环境又得安装一遍环境依赖?

    我会发现每次搞这些都要耗费一大堆时间,于是想到以前也有编译打包可执行文件,如Windows exe文件直接执行。

    一、简介 PyInstaller

    PyInstaller是一个用于将Python程序转换为独立的可执行文件的工具。使用PyInstaller,您可以将Python程序编译打包为单个可执行文件,该文件可以在没有Python解释器的计算机上运行,但是它不是交叉编译器,既不能夸操作系统编译打包,比如Windows只能编译打包为exe,不能编译为Linux、mac等操作系统。

    官方文档:https://pyinstaller.org/en/stable

    以下是使用PyInstaller将Python程序编译打包为可执行文件的基本步骤:

    1、确保已经安装了PyInstaller。如果没有安装,可以使用以下命令进行安装:

    pip install pyinstaller
    
    • 1

    2、打开终端或命令提示符,并导航到包含您的Python程序的目录。

    3、运行以下命令来将Python程序打包为可执行文件:

    pyinstaller your_script.py
    
    • 1

    其中your_script.py是您的Python程序的文件名。

    4、PyInstaller将在当前目录中创建一个名为dist的文件夹,其中包含生成的可执行文件。在Windows上,可执行文件将具有.exe扩展名,而在Linux和Mac上则没有扩展名。
    截图
    5、pyinstaller 命令部分简介

    pyinstaller --help
    
    • 1
    • -F:将所有文件打包为一个单独的可执行文件(意思是所有依赖)。
    • -D:将所有文件打包为一个目录,包含可执行文件和所有依赖的文件。
    • -c:将程序与命令提示符结合在一起,以便在命令提示符下运行。
    • -d:将调试信息打包进可执行文件中。
    • –onefile:将所有文件打包为一个单独的可执行文件。
    • -o:指定输出文件的位置。
    • -w:打包为窗口文件。
    • -i:指定ico。

    我最常用的为:

    pyinstaller -F -i xxx.ico xxx.py
    
    • 1

    二、实践 demo

    1、script.py

    while 1:
        word = input("请输入需要打印的字符:")
        print(word)
        if word.lower() == 'q':
            break
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、ico
    可以自行找一个

    3、运行命令

    pyinstaller -F -i ./script.ico script.py
    
    • 1

    在这里插入图片描述
    4、运行可执行文件 Windows
    由于是Windows下编译打包,则为exe,直接双击运行。
    在这里插入图片描述
    5、运行可执行文件 Linux
    Linux打包命令也是一致的。

    ./script
    
    • 1

    在这里插入图片描述


    三、编译打包踩坑

    pyinstaller -F -i ./desc/build.ico ppl.py
    
    • 1

    1、踩坑1:Plugin already registered

    依赖一般都会打入,但是其中也有入到坑,比如 pytest

    import pytest
    from allure_pytest import plugin as allure_plugin
    # pytest.main(argv)
    pytest.main(argv, plugins=[allure_plugin])  # todo use package
    
    • 1
    • 2
    • 3
    • 4

    当我编译打包时需要将 allure_plugin 依赖打入,但是在ide中运行又报错,于是只能改为:

    import pytest
    from allure_pytest import plugin as allure_plugin
    pytest.main(argv)
    # pytest.main(argv, plugins=[allure_plugin])  # todo use package
    
    • 1
    • 2
    • 3
    • 4

    pytest.main(argv) 才得以解决,报错如下:
    ValueError: Plugin already registered: allure_pytest= 错误截图


    2、踩坑2:OSError 句柄无效

    1、打包后执行exe发现以下错误:

    Traceback (most recent call last):
      File "", line 1, in <module>
    OSError: [WinError 6] 句柄无效。
    
    • 1
    • 2
    • 3

    后看到是loguru日志模块报错:
    也看到了此 issues 但是没有实际解决。

    2、于是在运行时添加一个自定义参数表示日志是否用 loguru
    默认是用,如果添加参数 --colour=0 则表示不使用loguru。
    部分代码改动如下:类 PplLog 打印 print 分别有使用到loguru的方法一致,这样代码改动最小了。
    错误截图
    3、打包测试
    发现正常了,应该就是这个原因 issues 但貌似没有看到更好的解决办法,只能先这样了。
    运行截图


    四、总结

    优点:

    • 方便、快捷、在可执行操作系统中一键运行。
    • 工具化,他人使用可不再需关注代码、环境依赖等。

    缺点:

    • 不支持跨系统编译打包。
    • 一些改动又得重新编译打包、发包。
    • 编译时可能会遇到问题,又比如编译后执行出现问题,也得花时间去解决。

    怎么总结下来是弊大于利?没有最好的语言或工具,适合的才是最好。
    所以按需择用!

    我的踩坑代码示例:
    github
    gitee

    在这里插入图片描述

  • 相关阅读:
    spring boot3.x集成swagger出现Type javax.servlet.http.HttpServletRequest not present
    Java【并发】面试题
    示例 方法的重载 221107
    数据结构--------排序方法
    七叶皂苷/鼠尾草酸/氟伐他汀/替米沙坦/甘氨鹅去氧胆酸/绿原酸(CA)/厄洛替尼牛血清白蛋白纳米粒
    UI/UX+前端架构:设计和开发高质量的用户界面和用户体验
    【云原生 | Kubernetes 系列】--Gitops持续交付和持续Tekton Triggers
    渗透测试--4.捕获和监听数据
    已解决:oracle新增列字段报错,ORA-00972:identifier is too long
    使用echarts实现立体-柱状图
  • 原文地址:https://blog.csdn.net/qq_42675140/article/details/132776385