3

次のコードでは、2 つの英語テキストの間に 2 行の英語テキストと 1 行のルーマニア語テキストが表示されますが、英語テキストしか表示されません (翻訳の切り替えは機能しません)。

main.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

card.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

andファイルを生成するためにxgettextandを使用しました。msgfmt.po.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

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 に答える
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 に答える
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

免責事項 Python アプリケーションで gettext を機能させる前に、これを試みないでください。その場でロケール (言語) を変更できることを含みます。これらは小さな偉業ではありません。これにより、混乱の 99% が取り除かれます。その後、それは機能するか、機能しないかのどちらかです。私はそれがうまくいくと言っています!

于 2013-04-08T02:56:11.563 に答える