python gettext_22.1. gettext — 多语种国际化服务 — Python 2.7.18 文档

22.1.3.Internationalizing your programs and modules¶

Internationalization (I18N) refers to the operation by which a program is made

aware of multiple languages. Localization (L10N) refers to the adaptation of

your program, once internationalized, to the local language and cultural habits.

In order to provide multilingual messages for your Python programs, you need to

take the following steps:

prepare your program or module by specially marking translatable strings

run a suite of tools over your marked files to generate raw messages catalogs

create language specific translations of the message catalogs

use the gettext module so that message strings are properly translated

In order to prepare your code for I18N, you need to look at all the strings in

your files. Any string that needs to be translated should be marked by wrapping

it in _('...') — that is, a call to the function _(). For example:

filename = 'mylog.txt'

message = _('writing a log message')

fp = open(filename, 'w')

fp.write(message)

fp.close()

In this example, the string 'writing a log message' is marked as a candidate

for translation, while the strings 'mylog.txt' and 'w' are not.

The Python distribution comes with two tools which help you generate the message

catalogs once you’ve prepared your source code. These may or may not be

available from a binary distribution, but they can be found in a source

distribution, in the Tools/i18n directory.

The pygettext 3 program scans all your Python source code looking

for the strings you previously marked as translatable. It is similar to the GNU

gettext program except that it understands all the intricacies of

Python source code, but knows nothing about C or C++ source code. You don’t

need GNU gettext unless you’re also going to be translating C code (such as

C extension modules).

pygettext generates textual Uniforum-style human readable message

catalog .pot files, essentially structured human readable files which

contain every marked string in the source code, along with a placeholder for the

translation strings. pygettext is a command line script that supports

a similar command line interface as xgettext; for details on its use,

run:

pygettext.py --help

Copies of these .pot files are then handed over to the individual human

translators who write language-specific versions for every supported natural

language. They send you back the filled in language-specific versions as a

.po file. Using the msgfmt.py 4 program (in the

Tools/i18n directory), you take the .po files from your

translators and generate the machine-readable .mo binary catalog files.

The .mo files are what the gettext module uses for the actual

translation processing during run-time.

How you use the gettext module in your code depends on whether you are

internationalizing a single module or your entire application. The next two

sections will discuss each case.

22.1.3.1.Localizing your module¶

If you are localizing your module, you must take care not to make global

changes, e.g. to the built-in namespace. You should not use the GNU gettext

API but instead the class-based API.

Let’s say your module is called “spam” and the module’s various natural language

translation .mo files reside in /usr/share/locale in GNU

gettext format. Here’s what you would put at the top of your

module:

import gettext

t = gettext.translation('spam', '/usr/share/locale')

_ = t.lgettext

If your translators were providing you with Unicode strings in their .po

files, you’d instead do:

import gettext

t = gettext.translation('spam', '/usr/share/locale')

_ = t.ugettext

22.1.3.2.Localizing your application¶

If you are localizing your application, you can install the _() function

globally into the built-in namespace, usually in the main driver file of your

application. This will let all your application-specific files just use

_('...') without having to explicitly install it in each file.

In the simple case then, you need only add the following bit of code to the main

driver file of your application:

import gettext

gettext.install('myapplication')

If you need to set the locale directory or the unicode flag, you can pass

these into the install() function:

import gettext

gettext.install('myapplication', '/usr/share/locale', unicode=1)

22.1.3.3.Changing languages on the fly¶

If your program needs to support many languages at the same time, you may want

to create multiple translation instances and then switch between them

explicitly, like so:

import gettext

lang1 = gettext.translation('myapplication', languages=['en'])

lang2 = gettext.translation('myapplication', languages=['fr'])

lang3 = gettext.translation('myapplication', languages=['de'])

# start by using language1

lang1.install()

# ... time goes by, user selects language 2

lang2.install()

# ... more time goes by, user selects language 3

lang3.install()

22.1.3.4.Deferred translations¶

In most coding situations, strings are translated where they are coded.

Occasionally however, you need to mark strings for translation, but defer actual

translation until later. A classic example is:

animals = ['mollusk',

'albatross',

'rat',

'penguin',

'python', ]

# ...

for a in animals:

print a

Here, you want to mark the strings in the animals list as being

translatable, but you don’t actually want to translate them until they are

printed.

Here is one way you can handle this situation:

def _(message): return message

animals = [_('mollusk'),

_('albatross'),

_('rat'),

_('penguin'),

_('python'), ]

del _

# ...

for a in animals:

print _(a)

This works because the dummy definition of _() simply returns the string

unchanged. And this dummy definition will temporarily override any definition

of _() in the built-in namespace (until the del command). Take

care, though if you have a previous definition of _() in the local

namespace.

Note that the second use of _() will not identify “a” as being

translatable to the pygettext program, since it is not a string.

Another way to handle this is with the following example:

def N_(message): return message

animals = [N_('mollusk'),

N_('albatross'),

N_('rat'),

N_('penguin'),

N_('python'), ]

# ...

for a in animals:

print _(a)

In this case, you are marking translatable strings with the function N_(),

5 which won’t conflict with any definition of _(). However, you will

need to teach your message extraction program to look for translatable strings

marked with N_(). pygettext and xpot both support

this through the use of command line switches.

In Python 2.4 the lgettext() family of functions were introduced. The

intention of these functions is to provide an alternative which is more

compliant with the current implementation of GNU gettext. Unlike

gettext(), which returns strings encoded with the same codeset used in the

translation file, lgettext() will return strings encoded with the

preferred system encoding, as returned by locale.getpreferredencoding().

Also notice that Python 2.4 introduces new functions to explicitly choose the

codeset used in translated strings. If a codeset is explicitly set, even

lgettext() will return translated strings in the requested codeset, as

would be expected in the GNU gettext implementation.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值