I have the following code which should display two lines of English text and one line of Romanian text between the two English ones, but it only displays English text (the translation switching doesn't work):
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):
# ...
My directory structure is as follows:
.
├── 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
I used xgettext and msgfmt to generate the .po and .mo files.
The problem is that if I only load a single language, the text gets translated (I have to do this as the sole thing before any output is displayed).
#! /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
But if I want to change languages on the fly the output made by the first code snippet presented above won't be translated.
What I'm doing wrong? What did I understand wrong from the docs?
All gettext.install() does is define the _() function as something that translates text. In your first example, you do x = card.Rank() before your ro.install() call - and so the only time that j = _('Jack') is called, _() translates it into the default English. Subsequently, _() gets redefined to Romanian - but it never gets called again, and so never gets retranslated.
I expect this will work:
#! /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
Translations are typically for end-users, not developers. So leave your strings as literals in the code and only translate when you display them:
class Rank(object):
j = 'Jack'
q = 'Queen'
k = 'King'
a = 'Ace'
...
x = card.Rank()
print _(x.j), _(x.a), _(x.q), _(x.k)
Note that the string extraction tools won't be able to find these strings anymore unless you call them with _() somewhere in your code.
If you don't want to add the strings to the translation files manually, you could add something like this to the module:
if False:
_('Jack')
_('Queen')
_('King')
_('Ace')
Or this:
assert(_('Jack'))
assert(_('Queen'))
assert(_('King'))
assert(_('Ace'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With