pycharm python 程序打包相关

前言

终于入门了python打包这个大话题,将目前学到的技能分享一下。


pycharm启动虚拟环境pipenv 缩小打包

和很多博客说的一样,打包那么大是因为打包了多余的库,因此想要缩小就需要一个干净的,没有多余的库的环境进行打包。也就是虚拟环境。
想要在 pycharm 启动虚拟环境,先要安装一个 pipenv。按下 win+r 后输入 cmd 打开命令面板,输入 pip install pipenv 即可安装。

安装后,我们需要得到名为 “pipenv.exe” 文件的路径,也就是 pipenv 虚拟环境的安装路径。查看的方法有很多,或许是能力原因本人试过的都不怎么好使,还是最朴素的方法最稳定:

在这里插入图片描述
是的,直接点开此电脑在右上角搜索文件即可(慢是慢了点但是亲测有效)!
然后我们打开 pycharm 选择新建项目

pycharm python 程序打包相关_第1张图片

点击三角形符号, pycharm 就会为这个项目创建一个干净的虚拟环境。

pycharm python 程序打包相关_第2张图片

然后选择好虚拟环境的类型,也就是上面安装的 pipenv。
如果pipenv可执行文件那一栏是空着的,那么就把上一步中得到的 “pipenv.exe” 的路径复制过去即可。
一切就绪,点击创建。

至此如果都成功,那么恭喜你得到了一个干净的python编程环境,在这个环境下打包是最小的。但是具体实现还有一些细节。

点击左下方栏目中的 python 软件包,那么将会显示在当前环境下安装的所有的库
在这里插入图片描述
可以发现非常的干净,只有三个库。但是这么点库是无法达成项目需求的,因此我们需要添加软件包到当前环境上。
pycharm python 程序打包相关_第3张图片
这一步很重要,切记不要在本地的cmd pip install 安装第三方库后,直接在虚拟环境中使用,这样子库内还是会附带很多多余的东西,就丧失了使用虚拟环境的意义。

那么怎样在 pycharm 提供的虚拟环境下安装呢。

依旧是下方栏目,选择“终端”

在这里插入图片描述
然后就会出现一个类似cmd的控制台。或许这时候你就会迫不及待的在这里 pip install 各种各样的库,但是请注意,左上方这里显示了“本地”,这是本地的 cmd,并不是我们虚拟环境的。
pycharm python 程序打包相关_第4张图片

那么怎么打开虚拟环境的 cmd 进行安装呢,操作步骤非常简单。
点击“本地”旁边的向下箭头,选择 “command prompt” ,然后就切换到了虚拟环境提供的 cmd 了。
pycharm python 程序打包相关_第5张图片
pycharm python 程序打包相关_第6张图片
我们最终在这个地方 pip install Pyinstaller 以及其他各种的库,然后在这里输入 Pyinstaller 命令打包即可。

这个方法打包后效果非常显著,本人一个用本地 cmd 打包 300M 的项目用了虚拟环境后只有 10M。


Pyinstaller 将资源与程序一同打包

相信大家编写的程序都经常需要调用存在本地的各种图片啊字体什么的对吧。但是直接 Pyinstaller 却不能将这些资源一起打包进 exe 文件里。也就是说,如果打包后的程序按照程序中的对应路径中找不到资源,那么就会报错。
那不行啊,如果我们的程序不是在本机运行,那么难不成我们还要把资源一起和exe到处移动,多难看啊?于是就想,如何将资源一起打包进一个exe中呢。

首先,直接 Pyinstaller 打包,项目目录下会新增两个文件夹:dist、build。把这两个都删了。
是的,把这次打包出来的exe也删了。

Pyinstaller 打包后还会产生一个文件 XXX.spec,文件名就是打包的程序名。
这个 spec 文件中包含着打包的所有信息。他也许长这样:

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


block_cipher = None


a = Analysis(
    ['XXX.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='XXX',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=['XXX.ico'],
)

我们打包的信息里面应有尽有,最上面的['XXX.py'],是打包的程序名,最下面的 icon=['XXX.ico'],
是我们打包exe的图标。
既然我们在 Pyinstaller 时输入的信息里面都有,那么就可以利用这个文件,使我们的资源也加入打包队列。

binaries=[],就是用于打包资源的。
可以看到它默认是空的,如果我们要打包资源,就往里面增加元素即可。具体格式的话是一个二元组(url1,url2)

  • url1 是用字符串表示的要打包的资源的相对路径
  • url2 是用字符串表示的运行exe后要把资源解压到的文件夹的相对路径。如果想解压到根目录,那么url2就是 ‘.’(注意有点号)

例如我要将 logo.png 和 air_mitalic.ttf 一起打包进 exe 。其中,logo.png 和 air_mitalic.ttf 存放在项目的根目录,打包解压后我想把他们再次放到根目录,那么 spec 文件应该修改为

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


block_cipher = None


a = Analysis(
    ['function_vision.py'],
    pathex=[],
    binaries=[('air_mitalic.ttf','.'),('logo.png','.')],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='function_vision',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=['logo.ico'],
)

修改好 spec 文件后,我们直接打包 spec 文件。在 cmd 中输入 Pyinstaller XXX.spec 即可。注意不要加 -F-D 和其他打包 .py 文件时的命令。

打包完之后仍然会出现一个存放在 dist 文件夹中的exe文件,但是我发现运行他是还是资源路径错误报错。
最终,在这篇博客中找到了解决方法。

Pyinstaller打包用spec添加资源文件,亲测可用

原来是因为打包后的资源解压到了一个奇怪的临时目录下面,因此原程序找不到。
那么我们就修改源程序。怎么改,我们使用前人的经验,在程序中写下一个路径解析函数

def resurce_path(relative_path):
    base_path=getattr(sys,'_MEIPASS',path.dirname(path.abspath(__file__)))  
    return path.join(base_path,relative_path)

每当在代码中需要调用资源的时候加上一个路径解析即可。

logo=pygame.image.load(resurce_path("logo.png"))

这样子,我们就可成功得到资源解压后所在的路径。

这个方法同样来自 Pyinstaller打包用spec添加资源文件,亲测可用,这里仅为引用。

亲测打包后的exe可以得到资源,这样子打包就免去了网上的一些 base64 转码法。

你可能感兴趣的:(python,python,pycharm,开发语言)