3

我有以下代码应该显示两行英文文本和两行英文文本之间的一行罗马尼亚语文本,但它只显示英文文本(翻译切换不起作用):

主要.py:

#! /usr/bin/env python2.7

import gettext
gettext.install('messages', '../i18n', unicode=True)

import card

if __name__ == '__main__':
    x = card.Rank()
    print x.j, x.a, x.q, x.k

    ro = gettext.translation('messages', localedir='../i18n', languages=['ro'])
    ro.install()

    print x.j, x.a, x.q, x.k

    en = gettext.translation('messages', localedir='../i18n', languages=['en'])
    en.install()

    print x.j, x.a, x.q, x.k

卡片.py

class Suit(object):
    clubs = _('Clubs'),
    diamonds = _('Diamonds'),
    hearts = _('Hearts'),
    spades = _('Spades')


class Rank(object):
    j = _('Jack')
    q = _('Queen')
    k = _('King')
    a = _('Ace')


class Card(object):
    # ...

我的目录结构如下:

.
├── i18n
│   ├── en
│   │   └── LC_MESSAGES
│   │       └── messages.mo
│   ├── en.po
│   ├── en_US.po
│   ├── ro
│   │   └── LC_MESSAGES
│   │       └── messages.mo
│   ├── ro.po
│   └── ro.pot
├── Makefile
├── README.md
└── src
    ├── card.py
    ├── card.pyc
    ├── deck.py
    └── main.py

我使用xgettextandmsgfmt来生成.poand.mo文件。

问题是如果我只加载一种语言,文本就会被翻译(在显示任何输出之前我必须这样做)。

#! /usr/bin/env python2.7
import gettext

if __name__ == '__main__':
    ro = gettext.translation('messages', localedir='../i18n', languages=['ro'])
    ro.install()

    import card
    x = card.Rank()
    print x.j, x.a, x.q, x.k

但是,如果我想即时更改语言,则不会翻译上面显示的第一个代码片段的输出。

我做错了什么?我从文档中理解错了什么?

4

3 回答 3

1

翻译通常适用于最终用户,而不是开发人员。因此,将您的字符串保留为代码中的文字,并且仅在显示它们时进行翻译:

class Rank(object):
    j = 'Jack'
    q = 'Queen'
    k = 'King'
    a = 'Ace'

...

    x = card.Rank()
    print _(x.j), _(x.a), _(x.q), _(x.k)

请注意,字符串提取工具将无法再找到这些字符串,除非您在代码中的某处使用 _() 调用它们。

如果您不想手动将字符串添加到翻译文件中,您可以在模块中添加如下内容:

if False:
    _('Jack')
    _('Queen')
    _('King')
    _('Ace')

或这个:

assert(_('Jack'))
assert(_('Queen'))
assert(_('King'))
assert(_('Ace'))
于 2013-03-21T20:08:42.463 回答
1

gettext.install() 所做的只是将 _() 函数定义为翻译文本的东西。在您的第一个示例中,您x = card.Rank()在 ro.install() 调用之前执行此操作 - 因此唯一一次j = _('Jack')调用 _() 会将其翻译为默认英语。随后, _() 被重新定义为罗马尼亚语 - 但它再也不会被调用,因此永远不会被重新翻译。

我希望这会起作用:

#! /usr/bin/env python2.7

import gettext
gettext.install('messages', '../i18n', unicode=True)

import card

if __name__ == '__main__':
    x = card.Rank()
    print x.j, x.a, x.q, x.k

    ro = gettext.translation('messages', localedir='../i18n', languages=['ro'])
    ro.install()

    x = card.Rank()
    print x.j, x.a, x.q, x.k

    en = gettext.translation('messages', localedir='../i18n', languages=['en'])
    en.install()

    x = card.Rank()
    print x.j, x.a, x.q, x.k
于 2013-02-18T22:56:32.557 回答
0
x = card.Rank() 
print _(x.j), _(x.a), _(x.q), _(x.k)

完全有效!

是的,字符串文字必须在您的代码中的某个位置。

字符串文字不必位于显示文本的同一模块中。将字符串文字放在同一个模块中并不好看(不是 OOP)。

使用 py v2.7 / gtk v2.24.10 / gettext 0.18.1 测试成功

python
import gtk 
gtk.gtk_version
(2, 24, 10)

gettext --version
gettext (GNU gettext-runtime) 0.18.1

免责声明 在让 gettext 为您的 python 应用程序工作之前不要尝试这样做。包括能够即时更改语言环境(语言)。这些都是不小的壮举。这将消除 99% 的混乱。然后它要么工作要么不工作。我说它会起作用的!

于 2013-04-08T02:56:11.563 回答