Python:使用pyinstaller打包含有gettext locales语言环境的项目
问题
如何使用 pyinstaller 打包使用了 gettext 本地化的项目,最终只生成一个 exe 文件
起因
最近在用 pyhton 做一个图片处理的小工具,顺便接触了一下 gettext,用来实现本地化化中英文转换。项目主要结构如下:
.
|--src # 源码
| |--package1
| |--package2
| |--locales # 本地化文件
| | |--en # 英文
| | | |--LC_MESSAGES
| | | |--en.mo
| | |--zh # 中文
| | |--LC_MESSAGES
| | |--en.mo
| |--GUI.py # 界面
| |--main.py # 主程序
直接使用 pyinstaller -F src\main.py 命令进行打包,打包后运行在 dist 文件夹中生成的 main.exe 会报错。原因是 gettext 找不到本地化文件。但如果试着将 locales 文件夹复制到 main.exe 的目录下程序能正常运行,说明 pyinstaller 在打包时不会将 locales 文件夹打包进去。
复制 locales 文件夹到可执行文件目录下固然可以运行,但这样用起来会很麻烦。
解决方案
目标是将 locales 目录一起打包进 exe 文件中,查阅 pyinstaller 的官方文档,了解到执行之前的 pyinstaller -F src\\main.py 命令会在目录下生成一个 .spec 文件,pyinstaller 通过该文件的内容来构建应用程序。
the first thing PyInstaller does is to build a spec (specification) file myscript.spec. That file is stored in the --specpath directory, by default the current directory.
The spec file tells PyInstaller how to process your script. It encodes the script names and most of the options you give to the pyinstaller command. The spec file is actually executable Python code. PyInstaller builds the app by executing the contents of the spec file.
使用记事本打开,.spec 文件里面大致长这样(来自官方例子)
block_cipher = None
a = Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,... )
coll = COLLECT(...)
其中,Analysis 里面有个 datas 参数,用于存放非二进制文件,也就是我们想让程序包含的静态文件。我们只要把 locales 目录填到这里面打包就会添加进去。当然不是填一个路径就好了,data 的格式如下:
--add-data <SRC;DEST or SRC:DEST>
SRC 就是未打包前的文件路径,DEST 是打包后文件的路径。以我的项目为例,打包前 locales 在 src/locales,打包后我想讲里面的文件放到临时目录的根目录下就填 ./locales,临时目录是什么后面讲。于是在我的 .spec文件里 datas 处就写成 datas=[("src/locales","./locales")]。如果有多个路径就以这样形式 datas=[(src1, dest1), (src2, dest2), ...]就OK。
这样打包部分的配置就改完了,不要急,还要改下源代码。exe 文件在运行时会生成一个临时目录,我们之前 datas 中的文件也会在该目录下。看看你的源码,如果调用资源用的是相对路径,那读取的是 exe 文件当前的目录,必然是找不到资源的。所以要把源码中相对路径改成临时目录的绝对路径。
sys 中的 _MEIPASS 属性存储了临时目录路径,直接获取即可。如果程序运行环境是打包后的,那么在 sys 中会添加一个 frozen 属性,通过能不能获取 frozen 属性可以判断当前环境是打包前还是打包后,具体详情请查阅 pyinstaller 官方文档(末尾有地址)。打包前就不需要获取临时目录路径了,直接用文件所在目录路径就行。
注意:打包后环境 file 属性不生效
import sys
import os
if getattr(sys, 'frozen', None):
dir = sys._MEIPASS
else:
dir = os.path.dirname(__file__)
获取路径 dir,可以使用 os.path.join() 来拼接路径,把源码中调用 datas 中资源地方的路径改成 os.path.join(dir, <打包后相对路径>)
如我的项目中原来的 './locales' 处就变成了 os.path.join(dir, 'locales')
最后一步,打包!不要再输之前的命令了,要使用改过之后的 .spec 文件进行打包,输入 pyinstaller -F 文件名.spec 就完成了。
参考资料
- pyinstaller 文档:Using Spec Files
- pyinstaller 文档:Run-time Information
Python:使用pyinstaller打包含有gettext locales语言环境的项目的更多相关文章
- python用pyinstaller打包成exe文件
版本为Python2.7 一.安装Pyinstaller 1.安装pywin32 下载安装文件:查找到跟自己适用的python版本及window系统版本匹配的pywin32,下载后安装 使用pip命 ...
- 【Python】pyinstaller打包运行报错failed to execute script main
前言 最近用pyinstaller打包的时候一直报"failed to execute script main". 最终使用"pyinstaller --hidden-i ...
- python 使用pyinstaller打包程序
使用pyinstaller 打包.py脚本,在其他计算机可以直接运行,不需要python环境 安装pyinstaller库 pip install pystaller 打包程序 pyinstaller ...
- Python | 用Pyinstaller打包发布exe应用
参考:https://jingyan.baidu.com/article/a378c960b47034b3282830bb.html https://ask.csdn.net/questions/72 ...
- python使用Pyinstaller打包
一.前言 python文件打包,将.py文件转化成.exe文件(windows平台),可以使用Pyinstaller来打包 Pyinstaller可以在全平台下使用,但是请注意打包生成的文件不能在全平 ...
- python pyinstaller 打包exe报错
今天用python 使用pyinstaller打包exe出现错误 环境pyqt5 + python3.6 在导入pyqt5包之前加上如下代码 import sysimport osif hasattr ...
- 利用PyInstaller打包exe文件
前言 平常我们通过Python写完一些小脚本之后,如果使用不频繁的话,一般会选择在DOS界面直接跑脚本,或者在IDE中运行.但当我们需要频繁使用某些脚本,或者在没有Python环境的机器上也能顺利运行 ...
- pyinstaller打包python文件成exe(原理.安装.问题)
py文件打包成exe文件的方式一共有三种:py2exe.PyInstaller和cx_Freeze 本文分四个步骤来详讲如何用PyInstaller将py文件打包成exe文件 1. PyInstall ...
- 用PyInstaller打包用PyQt5编写的python程序
0.背景 本弱初学PyQt5,写了一个GUI小程序,但在用PyInstaller打包时出现了不少问题,现将几个比较大的问题记录如下,希望以后能记住. 1. 资源打包 首先是资源打包的问题,我写的程序引 ...
随机推荐
- 【LeetCode】694. Number of Distinct Islands 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...
- 【LeetCode】622. Design Circular Queue 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 用直的代替弯的 数组循环利用 日期 题目地址:htt ...
- Laravel 使用 maatwebsite/excel 时长数字出现科学计数法的解决办法
在使用 maatwebsite/excel 包导出Excel的时候,有的单元格里会存放手机号等一大串的数字,这一串数字会被Excel软件处理为科学计数法,在后续处理数据的时候会产生不小的麻烦,一个个去 ...
- Direct and Indirect Effects
目录 概 主要内容 CDE NDE NIE TDE, TIE, PDE, PIE Judea Pearl. Direct and indirect effects. In Proceedings of ...
- Distillation as a Defense to Adversarial Perturbations against Deep Neural Networks
目录 概 主要内容 算法 一些有趣的指标 鲁棒性定义 合格的抗干扰机制 Nicolas Papernot, Patrick McDaniel, Xi Wu, Somesh Jha, Ananthram ...
- Electron 使用 Tray设置图标的路径问题
问题报错信息如图 上面的代码在dev模式下不报错,但是在build后,安装后,运行会提示错误,错误信息的大意是参数错误,原因应该是安装后的图片文件路径有问题,这块没有详细研究解决上面的问题的方法,是使 ...
- sping练习,在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台。
相关 知识 >>> 相关 练习 >>> 实现要求: 在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台.要 ...
- JS 数组的基本使用和案例
知识点汇总: 数组:就是一组数据的集合,存储在单个变量的方式 自变量创建数组 var 数组名字 = ['a','b'] // []里面的是数据的元素,可为任意字符类型 利用new创建数组 var 数组 ...
- SQL怎么求多列的和?
日常比较常使用的SQL,查询各科的总分,并求出总分大于240的学生名字和总分,如图,要求出linux.Mysql.Java三科的总分,并查处总分大于240的学生姓名和总分 可能你会想到sum,但是su ...
- win 10 遇到某文件一直在占用导致无法关闭,或者去任务管理器找不到服务怎么办?具体解决
1. 打开 cmd 指令框 ,输入 perfmon 回车 就会出来这个 点击 打开资源监视器, 在句柄搜索框搜索 那个占用资源的文件或软件关键词 ,如下 搜索酷狗 将有关的选项,右键选中后 打开菜单 ...