前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最详细的Python打包工具:Pyinstaller实战指南,如丝滑般体验

最详细的Python打包工具:Pyinstaller实战指南,如丝滑般体验

作者头像
一墨编程学习
发布2019-05-15 13:54:27
1.8K0
发布2019-05-15 13:54:27
举报

1. 安装

这个很简单,直接 pip install pyinstaller 就好。

⚠️注意了:你要编译成exe,建议你省心点的在windows上用pyinstaller,如果你要mac app的,那就用mac编译。

我今天就以windows为例

2. 简单使用

这个也很简单,网上一抓一大把,我这里就不赘述了,无非就是那么几个命令:

pyinstaller -F 项目主文件(或者是单一脚本)

3. 参数说明

-F,打包所有的依赖包在一个exe中,包括你自己的模块、内置模块以及第三方模块。

-c,如果你是命令行窗口,就要加上这个参数。

-w,窗口程序,比如你用了PyQt。

4. 高级用法:配置文件

.spec,这个文件非常重要,我们可以通过编辑这个文件来打包我们的项目,类似DockerFile。

我给大家贴一个我的:

代码语言:javascript
复制
# -*- mode: python -*-

block_cipher = None

a = Analysis(['C:\\app\\main.py'],
            pathex=['C:\\'],
            binaries=[],
            datas=[
                ('C:\\data\\input\\builtin\\*.xlsx', '.\\data\\input\\builtin\\'),
                ('C:\\data\\input\\*.xlsx', '.\\data\\input\\'),
                ('C:\\data\\output\\', '.\\data\\output\\'),
                ('C:\\log\\', '.\\log\\'),
                ('C:\\app\\db\\', '.\\app\\db\\')
            ],
            hiddenimports=['numpy', 'pandas'],
            ...
            )

pyz = PYZ(a.pure, a.zipped_data,
            cipher=block_cipher)

exe = EXE(pyz,
         ...
         )

这其实就是一个python文件,只不过后缀是spec罢了。

.spec一共会有4个对象,分别是:Analysis、PYZ、EXE、COLLECT。

Analysis用处最多,一个个解释:

  • 第一个参数,是指定我们整个项目的主程序,也就是我们的入口文件。
  • pathex,就是我们的工作目录
  • datas,存放我们的数据。

好了,说到这里就要好好说一说这个Pyinstaller的工作流程了。当我们双击编译好的exe后,他是会创建一个临时目录,把所有需要用的包都解压到那里,然后执行。执行完毕后,临时文件夹就消失了。

这和我们有什么关系呢?想一下,如果你的项目中需要去读取某些文件,甚至是用户的输入参数,怎么办?打包出来的exe 是没有办法通过直接指定参数,类似:python main.py --input=*.xlsx 来读取文件的,因为我之前说了,在执行的时候会把项目解压到一个临时目录,所以原来项目中写好的相对路径也不管用。

为此,我们需要把host上的实际文件给copy到那个临时目录下,所以这个datas的作用就是这个,我的文件中,我把host下的 C:\data\input\builtin*.xlsx文件都copy到临时目录的 data\input\builtin 下面。

hiddenimports ,继续说下去,PyInstaller有时候无法侦察到全部的依赖包,怎么办?我们可以在这个后面加,把PyInstaller编译出来的exe在运行的时候报的缺少模块给写里面。

⚠️注意了: pandas 和 numpy 有个很奇怪的地方,就是引用了 pandas 的地方,如果没有引用 numpy ,就会报错。所以你可以在主入口上面加一个 import numpy 。

⚠️注意了:直接 import numpy 还是会报错。怎么办?在 import numpy 下面加 import numpy.core._dtype_ctypes

5. 临时目录

那刚刚说的临时目录在代码里怎么处理呢,如果代码中还是老样子处理相对路径,一定是找不到的。

官方文档中给出了这么一段:

Your app should run in a bundle exactly as it does when run from source. However, you may need to learn at run-time whether the app is running from source, or is “frozen” (bundled).

代码语言:javascript
复制
import sys
if getattr( sys, 'frozen', False ) :
      # running in a bundle
      basedir = sys._MEIPASS
else :
      # running live

所以在你的项目中,如果有配置文件的话,就在那里加上这一段,然后在bundle中添加你的新路径,else还是你的老代码。

这个 sys._MEIPASS 是个特殊的值,是在Pyinstaller打包的时候才会添加的临时变量,通过这个变量我们可以获取到在执行exe时候的临时目录。

这对代码的改动是最小的。

6. 编译打包

最后,我们执行 python xxx.spec 就好了。打包的可执行文件会在dist里,build中是一些打包时候需要的文件。

输出中最后有 successfully 字样,就算成功了。他也会告诉你,exe出现在哪个位置。

当然不是说这样就万无一失了,别人也可以反编译你的exe,所以我们可以在打包的时候用Cython去编译一次,把混淆过的代码打包。这样的话难度就增加了,同时再加上mac地址绑定,这里就有多种思路了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.05.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2. 简单使用
  • 3. 参数说明
  • 4. 高级用法:配置文件
  • 5. 临时目录
  • 6. 编译打包
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档