用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(三)

简介: 用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(三)

2、修改文件打开函数

这里有三种方法,前两种是我的方法,最后一种是网上别人的方法。

① 引入特定的模块

这个模块的代码很简单,放在下面,一定要将模块命名为 _.py,并在引用其他第三方模块之前就引用它,但又一定要在下划线开头的模块之后引用(否则会有 BUG),它在主 Python 文件里引用一次即可(其他的文件不用引用)!它可以将 open 函数改成我们想要的,而且原来的代码还完全不用修改!

import builtins
def wrapper(function):
    def _open(*args, **kw):
        """ 修改路径 """
        _args = list(args)
        _args[0] = __file__[:-4] + args[0]
        if kw.get('file'):
            kw['file'] = __file__[:-4] + kw['file']
        return function(*_args, **kw)
    return _open
setattr(builtins, 'open', wrapper(open))

这里的 __file__ 是 Python 文件的属性,是一个字符串,为该文件的绝对路径,不管该文件在哪里,__file__ 都是对应的绝对路径。然后我们用写一个 wrapper 函数充当装饰器,将内置的 open 函数包装一下。再引入 builtins 模块(内置函数和类的模块),给其添加一个名为 open 新属性以覆盖原来的 open 函数,并对该项目整体生效即可!


这种方法的好处在于,它只需要在主文件里引用一次即可,其他的什么都不用改!(④ 特别注意 里的除外)

② 自己手动修改 open 函数修改路径

这个修改是在源代码中修改的(每一个用到了 open 函数的 Python 文件都要改一次),目的就是要让相对路径变成会根据主 Python 文件的路径而变化的绝对路径。修改的装饰器如下:

# 编写装饰器
def wrapper(function):
    def _open(*args, **kw):
        """ 修改路径 """
        args_list = list(args)
        key = '/'.join(__file__.split('\\')[:-1]) + '/'
        args_list[0] = key + args[0]
        if kw.get('file'):
            kw['file'] = key + kw['file']
        return function(*args_list, **kw)
    return _open
# 装饰内置函数open
open = wrapper(open)

把这段代码写在文件的开头即可(或者说在使用open函数之前)。

③ 网友的其他方法

他们就是写了这样一个函数来代替 open,也是手动修改的 open 函数,不得不说,看起来有点麻烦(每个用了 open 函数的 Python 文件都要引入 os 和 sys 模块)。

import os
import sys
def get_resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

其他的都是一样的。

④ 特别注意

这里还要提一下,无论是前面的哪一种方法,只要你使用了参数为路径的其他函数时,也要改一下,其实就是在相对路径前面加上方法②中的 key 即可。


其实直接方法③来代替也可以,但是功能上容易出错,而且如果 Python 文件较多,那么每个 Python 文件都这样引用两个模块(sys 和 os),看起来比较麻烦。


当我们使用了 tkinter 模块的时候,PhotoImage 类就是要这样写的一个例子(其中的 __init__ 方法用到了路径):

class PhotoImage(tkinter.PhotoImage):
    def __init__(self, *args, **kw):
        if kw.get('file'):
            key = '/'.join(__file__.split('\\')[:-1]) + '/'
            kw['file'] = key + kw['file']
        tkinter.PhotoImage.__init__(self, *args, **kw)

这个代码就要写在使用 PhotoImage 的开头,后续调用时就用这个 PhotoImage,使用其他模块时,遇到参数为路径的函数或类,都要这样修改。

最后一步,和之前的方法一样,打包你的程序即可!

打包实战

我这里以一个我的半成品为例,进行打包。项目是一个图形化界面的程序。我们要将其打包成只含有一个 exe 的文件。

打包方式的选择

我的项目里面包含多个 Python 文件,要用多 Python 文件打包方式;

项目比较大,为节省打包时间,并追求极致的 exe 大小,采用虚拟环境打包方式;

项目含有资源文件夹,采用包含资源文件的打包方式。

打包方式选择好了,开始打包!

打包全过程

项目全部文件(蓝色背景的是主文件)项目文件

包含四个 Python 文件、一个资源文件夹(res),资源文件夹里面又包含了一些子文件夹和 json 文件。

第一步:启动 Anaconda Prompt,切换至目标文件夹路径位置

cd C:\Users\小康\Desktop\SuperGameLauncher

第二步:启动虚拟环境(我的是一个纯净的、第三方包只有 Pyinstaller 的环境)

conda activate e1

启动虚拟环境切换至目标文件夹路径位置

第二步:启动虚拟环境(我的是一个纯净的、第三方包只有 Pyinstaller 的环境)

conda activate e1

启动虚拟环境

第四步:引入 _.py 模块(我的程序用到了大量 open 函数且涉及多文件)

_.py 自定义模块

引入 _ 模块

处理特殊的情况(tkintertools 模块里面有参数为路径的类):

处理特殊情况

第五步:编辑 spec 文件

修改图中标识的两处地方(_.py 不要忘记了)。

编辑 spec 文件

第六步:打包项目(注意这里的对象是 spec 文件)

Pyinstaller SuperGameLauncher.spec

准备打包

打包成功!

打包成功

第七步:检验打包效果

找到项目中的 dist 文件夹,打开后会有一个 exe 文件。对于我这个项目而言,这已经是非常小的大小了(50.8MB),毕竟资源文件就有 42.2MB,也就是说,除去资源文件,源代码占用的大小为 8.6MB!怎么样,是不是很不错呢?

dist 文件夹

双击运行!

成功运行

目录
相关文章
|
7天前
|
Python
Python Internet 模块
Python Internet 模块。
102 74
|
25天前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
104 63
|
27天前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
27天前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
6天前
|
安全 API C语言
Python程序的安全逆向(关于我的OPENAI的APIkey是如何被盗的)
本文介绍了如何使用C语言编写一个简单的文件加解密程序,并讨论了如何为编译后的软件添加图标。此外,文章还探讨了Python的.pyc、.pyd等文件的原理,以及如何生成和使用.pyd文件来增强代码的安全性。通过视频和教程,作者详细讲解了生成.pyd文件的过程,并分享了逆向分析.pyd文件的方法。最后,文章提到可以通过定制Python解释器来进一步保护源代码。
32 6
|
18天前
|
IDE 程序员 开发工具
Python编程入门:打造你的第一个程序
迈出编程的第一步,就像在未知的海洋中航行。本文是你启航的指南针,带你了解Python这门语言的魅力所在,并手把手教你构建第一个属于自己的程序。从安装环境到编写代码,我们将一步步走过这段旅程。准备好了吗?让我们开始吧!
|
27天前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
7月前
|
Python
使用PyInstaller将Python应用程序打包成EXE文件
使用PyInstaller将Python应用程序打包成EXE文件
855 0
|
IDE 开发工具 Python
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(二)
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(二)
817 0
|
C++ Python Windows
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(一)
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)(一)
421 0

热门文章

最新文章