在Python3.x中使用PyInstaller编译gettext语言环境

在Python3.x中使用PyInstaller编译gettext语言环境,python,python-3.x,localization,pyinstaller,gettext,Python,Python 3.x,Localization,Pyinstaller,Gettext,我用pyinstaller--onefile palc.py冻结了一个gettext本地化(英语和法语,但将来可能会更多)的Python脚本,它编译得非常完美,但当我试图运行它时,它试图使用存储在locales目录中的locales(这意味着如果我不使用locales目录分发包,它就找不到它们)如你所想,这是PyInstaller的一个主要缺点,几乎破坏了PyInstaller的功能——为了分发它,我必须提供一个目录和软件包,以便它工作——尽管,正如我将要向你展示的,它甚至不能工作 主要问题是:

我用
pyinstaller--onefile palc.py
冻结了一个
gettext
本地化(英语和法语,但将来可能会更多)的Python脚本,它编译得非常完美,但当我试图运行它时,它试图使用存储在
locales
目录中的locales(这意味着如果我不使用
locales
目录分发包,它就找不到它们)如你所想,这是PyInstaller的一个主要缺点,几乎破坏了PyInstaller的功能——为了分发它,我必须提供一个目录和软件包,以便它工作——尽管,正如我将要向你展示的,它甚至不能工作

主要问题是: 是否可以让PyInstaller使用
gettext
语言环境编译Python脚本(最好不要太难或需要大量重写)

编辑:我尝试编辑我的
palc.spec
,以下是新版本: 下面是编译包的输出:

>>> ./palc
--------------------------------------------------------------------------
                          Language Selection
--------------------------------------------------------------------------
1 - English // Anglais
2 - Francais // French
Type: 1
Traceback (most recent call last):
  File "/Users/computer/python-text-calculator/palc.py", line 30, in <module>
    l_translations = gettext.translation('base', localedir='locales', languages=["en"])
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/gettext.py", line 514, in translation
    raise OSError(ENOENT, 'No translation file found for domain', domain)
FileNotFoundError: [Errno 2] No translation file found for domain: 'base'
[19393] Failed to execute script palc
>。/palc
--------------------------------------------------------------------------
语言选择
--------------------------------------------------------------------------
1-英语//英语
2-法语//法语
类型:1
回溯(最近一次呼叫最后一次):
文件“/Users/computer/python text calculator/palc.py”,第30行,在
l_translations=gettext.translation('base',localedir='locales',languages=[“en”])
文件“/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/gettext.py”,第514行,翻译为
引发OSError(eNONT,“未找到域的翻译文件”,域)
FileNotFoundError:[Errno 2]未找到域“base”的翻译文件
[19393]无法执行脚本palc
这与未编辑
palc.spec
时的输出完全相同。此外,它使编译后的包成为一个目录(我在dist的
palc
目录中运行了
/palc
),因此我仍然需要分发一个目录。我需要的是一个与找到的文件类似的文件


有人能帮忙吗?谢谢!:D

首先,一旦规范文件生成,请将规范文件提供给pysintaller而不是Python文件:运行
pyinstaller palc.spec
而不是
pyinstaller palc.py
。否则,pyinstaller每次都会重置规范文件

然后,为了为onefile应用程序生成正确的规范文件,请使用
pyi makespec--onefile palc.py
。它生成一个规范文件,不包含
COLLECT
步骤和另一个
EXE
步骤

然后,您可以在spec文件中使用自定义python函数为您的地区构建
数据(请记住,spec文件只是一个具有自定义文件扩展名的python文件):

def get_locales_data():
区域设置_数据=[]
对于os.listdir(os.path.join('./locales'))中的区域设置:
locales\u data.append((
join('./locales',locale,'LC_MESSAGES/*.mo'),
join('locales',locale,'LC_MESSAGES')
))
返回locales\u数据
然后使用此函数的返回值作为
分析
步骤中数据参数的值:

a=分析(['palc.py'],
...
datas=get\u locales\u data(),
...)
然后,您必须调整代码以在正确的位置查找locales文件(根据运行时环境:打包还是不打包),但我没有更多的时间来开发答案的这一部分


为方便起见,下面是一个使用pyi makespec生成并修改为包含区域设置的正确specfile示例:

#-*-模式:python;编码:utf-8-*-
导入操作系统
分组密码=无
def get_locales_data():
区域设置_数据=[]
对于os.listdir(os.path.join('./locales'))中的区域设置:
locales\u data.append((
join('./locales',locale,'LC_MESSAGES/*.mo'),
join('locales',locale,'LC_MESSAGES')
))
返回locales\u数据
a=分析(['palc.py'],
pathex=['.],
二进制文件=[],
datas=get\u locales\u data(),
hiddenimports=[],
hookspath=[],
运行时挂钩=[],
不包括=[],
win\u no\u Preference\u redirects=False,
win_private_assemblies=False,
密码=分组密码,
无存档=假)
pyz=pyz(a.pure,a.zipped_数据,
密码=分组密码)
exe=exe(pyz,
a、 剧本,
a、 二进制文件,
a、 拉链,
a、 数据,
[],
name='palc',
debug=False,
引导加载程序\u忽略\u信号=False,
strip=False,
upx=真,
upx_exclude=[],
运行时\u tmpdir=None,
控制台=真)
问题是:
您的新
.spec
文件是正确的,您正在说明您想要在捆绑包中包含哪些文件,以及您想要将它们放在捆绑包中的什么位置

是你接触它们的方式导致了你的痛苦。
错误代码中的行
l\u translations=gettext.translation('base',localedir='locales',languages=[“en”])
建议您列出文件所在的目录
locales
,这实际上是有意义的,因为您声明它们应该在那里。。。但是
PyInstaller
的工作方式有点不同。由于您将其捆绑为一个文件,因此它实际上会在其他地方被
引导加载程序打开

如何修复它:
不要指定dir
locales
将其更改为:

从操作系统导入路径
bundle_dir=getattr(sys,'.'u MEIPASS',path.abspath(path.dirname(_file__)))#如果绑定,则获取bundle dir;如果未绑定,则仅获取_file__dir
locales\u dir=path.abspath(path.join(bundle\u dir,'locales'))
现在
locales\u dir
poi
>>> ./palc
--------------------------------------------------------------------------
                          Language Selection
--------------------------------------------------------------------------
1 - English // Anglais
2 - Francais // French
Type: 1
Traceback (most recent call last):
  File "/Users/computer/python-text-calculator/palc.py", line 30, in <module>
    l_translations = gettext.translation('base', localedir='locales', languages=["en"])
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/gettext.py", line 514, in translation
    raise OSError(ENOENT, 'No translation file found for domain', domain)
FileNotFoundError: [Errno 2] No translation file found for domain: 'base'
[19393] Failed to execute script palc