V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
firejoke
V2EX  ›  Python

记录踩到的 pyinstaller 打包 exe 的坑

  •  
  •   firejoke · 2018-08-02 13:33:28 +08:00 · 7358 次点击
    这是一个创建于 2306 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求:帮别人做一个统计 pdf 文档内词频的功能
    环境:python3.6

    >Package Version
    -------------- ---------
    altgraph==0.16.1
    atomicwrites==1.1.5
    attrs==18.1.0
    future==0.16.0
    jieba==0.39
    macholib==1.10
    more-itertools==4.2.0
    pdfminer3k==1.3.1
    pefile==2017.11.5
    pip==18.0
    pluggy==0.7.1
    ply==3.11
    py==1.5.4
    PyInstaller==3.3.1
    pytest==3.7.0
    setuptools==39.1.0
    six==1.11.0

    参考文档:
    https://www.jianshu.com/p/5a59b6985346
    https://www.crifan.com/use_pyinstaller_to_package_python_to_single_executable_exe

    坑:
    上述链接文档里,都是把环境和脚本打包成了一个 exe 文档
    在脚本目录用命令 pyinstaller -F -p venv_path (中间一定要有空格) you.py
    打包成一个文档后,报错在系统目录找不到 jieba 的 dict.txt
    因为 jieba 会去找它自带的 dict.txt 文档
    当你打包成一个文档的时候,貌似 pyinstaller 不会把你的 txt 文档打包进来,所以 jieba 回去系统目录去找,就会找不到,然后报错
    想到的第一个解决办法是改搜索路径,嫌麻烦,不改...
    第二个办法,既然不会打包 txt 文档,那我干脆不打包依赖库,只打包脚本,让它自己去搜索依赖
    pyinstaller -p venv_path (中间一定要有空格) you.py
    因为我需要黑终端输入路径,所以没有用 -w 参数
    在 dist 文件夹生成了一个以脚本名命名的文件夹,包含一堆配置文档和一个 脚本名.exe
    运行报错找不到当前目录下的 jieba
    遂把 venv/lib/python3.6/site-packages/ 下的所有文件拷过来
    双击成功 666
    26 条回复    2019-04-16 17:52:19 +08:00
    ifoolish
        1
    ifoolish  
       2018-08-02 13:59:07 +08:00 via iPhone
    格式好乱……一般大家都会写个博客记录一下
    H0TSp1RnG
        2
    H0TSp1RnG  
       2018-08-02 14:05:31 +08:00
    正好遇到一个打包的问题 我在 mac 环境下打包 但是目标运行环境是 win10 的 应该怎么弄
    OpenJerry
        3
    OpenJerry  
       2018-08-02 14:15:52 +08:00 via Android
    @H0TSp1RnG 用 windows 虚拟机打包吧,pyinstaller 好像不能跨平台打包
    firejoke
        4
    firejoke  
    OP
       2018-08-02 14:37:52 +08:00
    @ifoolish 最开始是 default 语法,预览的时候很好,发布后发现有一个写错了,就重新编辑了,结果就......
    firejoke
        5
    firejoke  
    OP
       2018-08-02 14:39:39 +08:00
    @H0TSp1RnG 看你的依赖库有没有像我这样的会有依赖的 txt 之类的文档,如果有,
    就按我的这个方法,亲测可以在 win10 运行
    firejoke
        6
    firejoke  
    OP
       2018-08-02 14:41:52 +08:00
    @OpenJerry
    @H0TSp1RnG 哦,对,你等等,我是分别在 Mac 和 win10 都打包测试过了,我试试 Mac 打包的放 win 可不可行
    firejoke
        7
    firejoke  
    OP
       2018-08-02 14:45:49 +08:00
    @H0TSp1RnG
    @OpenJerry
    试了,不行,必须在 win10 系统打包
    shootsoft
        8
    shootsoft  
       2018-08-02 15:05:00 +08:00
    xyfan
        9
    xyfan  
       2018-08-02 16:32:59 +08:00
    Pyinstaller 真的是大坑,pyqt 写了一个很小的程序,用-w 打包运行的时候报错,不用-w,带命令行运行就没问题,怎么也解决不了。(不是 std i/o 问题)
    OpenJerry
        10
    OpenJerry  
       2018-08-02 17:11:16 +08:00 via Android
    所以帮身边小伙伴做一些小工具的时候,我宁愿用 go 写
    firejoke
        11
    firejoke  
    OP
       2018-08-02 18:03:37 +08:00
    @xyfan 可能和我一样, 是依赖包的路径寻址问题, 我觉得要想优雅而彻底的解决, 只能改资源搜索路径


    @OpenJerry 别呀~python 这么优雅~


    @shootsoft 有点厉害! 你是怎么解决依赖库的路径搜索问题的?
    waterlaw
        12
    waterlaw  
       2018-08-02 19:40:24 +08:00 via Android
    我也遇到这个问题哎,qm 文件不会帮我打包。
    waterlaw
        13
    waterlaw  
       2018-08-02 19:41:34 +08:00 via Android
    还是用 c ++ 比较好, 打包后体积小
    shootsoft
        14
    shootsoft  
       2018-08-02 20:11:32 +08:00
    @firejoke 貌似我没碰上复杂的依赖...
    twistedmeadows
        15
    twistedmeadows  
       2018-08-02 20:21:42 +08:00 via Android
    以为有什么高级经验。结果也是这种粗暴解法。
    Python 就是这方面太不酷了,想跟小伙伴装个逼都装不了。
    firejoke
        16
    firejoke  
    OP
       2018-08-02 20:53:36 +08:00
    @waterlaw 应该还有更全的打包方法,不行就只有修改源码了

    @shootsoft 那也是幸运了~

    @twistedmeadows 哈哈哈~看情况来的嘛,如果没有特别的依赖文件之类的,就可以连着 QT 界面一起打包啊,
    做个小游戏、小工具什么的也不是不可以啊~
    XxxxD
        17
    XxxxD  
       2018-08-02 21:21:24 +08:00
    打包成 exe 会很大么?
    weyou
        18
    weyou  
       2018-08-02 21:33:40 +08:00 via Android
    @xyfan 可以试试在主文件开头设置 excepthook,将未知异常输出到文件来查看原因
    firejoke
        19
    firejoke  
    OP
       2018-08-02 21:36:39 +08:00
    @XxxxD 连着环境一起打包成一个就会很大,可以用 UPX 压缩

    @xyfan
    @waterlaw
    @twistedmeadows
    各位,找到一个可以给打包添加路径的方法
    http://ju.outofmemory.cn/entry/137370
    weyou
        20
    weyou  
       2018-08-02 21:42:46 +08:00 via Android
    @firejoke 打开 pyinstaller 生成的 spec 文件,你会发现有个搜索路径 pathex 可以设置,并且可以设置多个。

    如果程序中有要运行时读取的文件( text,图片等非 import 的文件),pyinstaller 是找不到的,这时可以将路径放到 datas 列表中让 pyinstaller 打包进去,

    其实这些 pyinstaller 自带的文档里都有明确的说明,楼主为什么不先读一遍呢
    itskingname
        22
    itskingname  
       2018-08-02 22:13:52 +08:00
    @weyou 因为他们只会用百度搜索中文博客看。
    firejoke
        23
    firejoke  
    OP
       2018-08-03 09:42:02 +08:00
    @itskingname 好好说话不会吗, 自卑感好点了吗
    firejoke
        24
    firejoke  
    OP
       2018-08-03 09:45:24 +08:00
    @weyou 说的对,当时只想着可能是命令问题,一心去找别人的解决方法,没想到去看官方文档,
    下次吸取教训, 我去试试能不能把 jieba 自带的 dict.txt 路径一起打进去
    firejoke
        25
    firejoke  
    OP
       2018-08-03 11:59:28 +08:00
    最后,结合官方文档 https://pyinstaller.readthedocs.io/en/v3.3.1/spec-files.html
    把 jieba 模块下的所有 txt 文档在 .spec 文件内加进去
    形式:
    datas = [ ('XXX.txt_path', 'jieba' ),('analyse/XXX.txt_path', 'jieba/analyse'),('finalseg/XXX.p_path','jieba/finalseg'),......]
    (非.py 文档以路径 , 模块名), 或者(非.py , 模块名 /包名)

    或者直接
    datas = [ (‘ jieba','jieba' ) ]

    这两个形式都可以
    然后 pyinstaller name.spec 运行一下就 OK 了
    VVTA
        26
    VVTA  
       2019-04-16 17:52:19 +08:00
    好久没来了.上来学习下哈.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2844 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:46 · PVG 16:46 · LAX 00:46 · JFK 03:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.