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】160. Intersection of Two Linked Lists 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 栈 日期 题目地址:https://leet ...
- Subsequence(hdu3530)
Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 数据结构作业——P53算法设计题(6):设计一个算法,通过一趟遍历确定长度为n的单链表中值最大的结点
思路: 设单链表首个元素为最大值max 通过遍历元素,与最大值max作比较,将较大值附给max 输出最大值max 算法: /* *title:P53页程序设计第6题 *writer:weiyuexin ...
- EMA
目录 源 设置 结果 源 Exponential moving average (EMA) 是一个非常有用的trick, 起到加速训练的作用. 近来发现, 该技巧还可以用于提高网络鲁棒性(约1% ~ ...
- IT6563替代芯片|DP转HDMI 2.0音视频讯号转换芯片|CS5263Capstpne
IT6563替代芯片|CS 5263|4LAN DP转HDMI 2.0音视频讯号转换芯片IT6563是一款4LAN EDP转HDMI2.0 HDMI2.0转换器芯片.IT6563FN结合Display ...
- JavaScript交互式网页设计作业目录(作业笔记)
JavaScript交互式网页设计笔记 • [目录] 我的大学笔记>>> 第1章 JavaScript基本语法>>> 1.1.4 使用 JavaScript 的 H ...
- MySQL数据操作与查询笔记 • 【第7章 连接查询】
全部章节 >>>> 本章目录 7.1 内连接查询 7.1.1 交叉连接(笛卡尔积) 7.1.2 内连接查询概要 7.1.3 内连接案例 7.1.4 自然连接 7.2 多表连 ...
- docker部署logstash
1.下载镜像 [root@vanje-dev01 ~]# docker pull logstash:7.0.1 2.安装部署 2.1 创建宿主映射目录 # mkdir /etc/logstash/ ...
- [ python应用 ] python递归搜索文件,支持搜索多个文件,支持自定义处理动作
写了一个PyQT界面的版本:https://github.com/LongchuanYu/pyqt_project PATH = r'E:\MyDocument\新しいフォルダー\' # 要搜索的目录 ...
- Zabbix监控报警Lack of free swap space on Zabbix server解决办法
故障描述: Lack of free swap space on Zabbix server 故障原因: 情况一:云主机:因为Zabbix监控没有考虑虚拟主机的swap分区情况. 情况二:物理主机:说 ...