Mar*_*ing 6 python localization gettext
我在编辑器中使用UTF-8,因此这里显示的所有字符串都是文件中的UTF-8.
我有一个像这样的python脚本:
# -*- coding: utf-8 -*-
...
parser = optparse.OptionParser(
description=_('automates the dice rolling in the classic game "risk"'),
usage=_("usage: %prog attacking defending"))
Run Code Online (Sandbox Code Playgroud)
然后我使用xgettext来解决所有问题并得到一个.pot文件,可以归结为:
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: auto_dice.py:16
msgid "automates the dice rolling in the classic game \"risk\""
msgstr ""
Run Code Online (Sandbox Code Playgroud)
之后,我使用msginit来获取de.po我填写的内容,如下所示:
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: auto_dice.py:16
msgid "automates the dice rolling in the classic game \"risk\""
msgstr "automatisiert das Würfeln bei \"Risiko\""
Run Code Online (Sandbox Code Playgroud)
运行脚本,我收到以下错误:
File "/usr/lib/python2.6/optparse.py", line 1664, in print_help
file.write(self.format_help().encode(encoding, "replace"))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 60: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
该错误意味着您在字节串上调用了编码,因此它尝试使用系统默认编码(Python 2上的ascii)将其解码为Unicode,然后使用您指定的任何内容对其进行重新编码.
通常,解决它的方法是s.decode('utf-8')在尝试使用字符串之前调用(或字符串所在的任何编码).如果您只使用unicode文字,它也可能有效:( u'automates...'这取决于字符串如何从.po文件中替换,我不知道).
Python 3中改进了这种令人困惑的行为,除非你明确告诉它,否则不会尝试将字节转换为unicode.
我怀疑是问题是由_("string")返回字节字符串而不是Unicode字符串引起的.
明显的解决方法是:
parser = optparse.OptionParser(
description=_('automates the dice rolling in the classic game "risk"').decode('utf-8'),
usage=_("usage: %prog attacking defending").decode('utf-8'))
Run Code Online (Sandbox Code Playgroud)
但这感觉不对.
ugettext或install(True)可能有所帮助.
在Python的gettext的文档给这些例子:
import gettext
t = gettext.translation('spam', '/usr/share/locale')
_ = t.ugettext
Run Code Online (Sandbox Code Playgroud)
要么:
import gettext
gettext.install('myapplication', '/usr/share/locale', unicode=1)
Run Code Online (Sandbox Code Playgroud)
我试图重现你的问题,即使我使用install(unicode=1),我得到一个字节字符串(str类型).
要么我错误地使用gettext,要么我在.po/.mo文件中缺少字符编码声明.
当我知道更多时,我会更新.
xlt = _('automates the dice rolling in the classic game "risk"')
print type(xlt)
if isinstance(xlt, str):
print 'gettext returned a str (wrong)'
print xlt
print xlt.decode('utf-8').encode('utf-8')
elif isinstance(xlt, unicode):
print 'gettext returned a unicode (right)'
print xlt.encode('utf-8')
Run Code Online (Sandbox Code Playgroud)
(另一种可能性是在.po文件中使用转义符或Unicode代码点,但这听起来并不好玩.)
(或者您可以查看系统的.po文件以了解它们如何处理非ASCII字符.)