gettext
— Multilingual internationalization services多语言国际化服务¶
Source code: Lib/gettext.py
The gettext
module provides internationalization (I18N) and localization (L10N) services for your Python modules and applications. gettext
模块为Python模块和应用程序提供国际化(I18N)和本地化(L10N)服务。It supports both the GNU gettext message catalog API and a higher level, class-based API that may be more appropriate for Python files. 它既支持GNU gettext消息目录API,也支持更适合Python文件的更高级别、基于类的API。The interface described below allows you to write your module and application messages in one natural language, and provide a catalog of translated messages for running under different natural languages.下面描述的界面允许您用一种自然语言编写模块和应用程序消息,并提供在不同自然语言下运行的翻译消息目录。
Some hints on localizing your Python modules and applications are also given.还提供了一些关于本地化Python模块和应用程序的提示。
GNU gettext API¶
The gettext
module defines the following API, which is very similar to the GNU gettext API. gettext
模块定义了以下API,它与GNU gettext API非常相似。If you use this API you will affect the translation of your entire application globally. 如果使用此API,将影响整个应用程序的全局翻译。Often this is what you want if your application is monolingual, with the choice of language dependent on the locale of your user. 如果应用程序是单语的,并且语言的选择取决于用户的语言环境,那么这通常就是您想要的。If you are localizing a Python module, or if your application needs to switch languages on the fly, you probably want to use the class-based API instead.如果您正在本地化Python模块,或者如果您的应用程序需要动态切换语言,则可能需要使用基于类的API。
-
gettext.
bindtextdomain
(domain, localedir=None)¶ Bind the domain to the locale directory localedir.将domain绑定到本地目录localedir。More concretely,更具体地说,gettext
will look for binary.mo
files for the given domain using the path (on Unix):localedir/language/LC_MESSAGES/domain.mo
, where language is searched for in the environment variablesLANGUAGE
,LC_ALL
,LC_MESSAGES
, andLANG
respectively.gettext
将使用路径(在Unix上)查找给定域的二进制.mo
文件:localedir/language/LC_MESSAGES/domain.mo
,其中language分别在环境变量LANGUAGE
、LC_ALL
、LC_MESSAGES
和LANG
中搜索。If localedir is omitted or如果省略localedir或为None
, then the current binding for domain is returned.None
,则返回domain的当前绑定。1
-
gettext.
bind_textdomain_codeset
(domain, codeset=None)¶ Bind the domain to codeset, changing the encoding of byte strings returned by the将domain绑定到代码集codeset,更改lgettext()
,ldgettext()
,lngettext()
andldngettext()
functions.lgettext()
、ldgettext()
、lngettext()
和ldngettext()
函数返回的字节字符串的编码。If codeset is omitted, then the current binding is returned.如果省略了codeset,则返回当前绑定。Deprecated since version 3.8, removed in version 3.10.自版本3.8起弃用,在版本3.10中删除。
-
gettext.
textdomain
(domain=None)¶ Change or query the current global domain.更改或查询当前全局域。If domain is如果domain为None
, then the current global domain is returned, otherwise the global domain is set to domain, which is returned.None
,则返回当前全局域,否则将全局域设置为domain,并返回。
-
gettext.
gettext
(message)¶ Return the localized translation of message, based on the current global domain, language, and locale directory.根据当前全局域、语言和区域设置目录返回message的本地化翻译。This function is usually aliased as此函数在本地命名空间中通常别名为_()
in the local namespace (see examples below)._()
(请参见下面的示例)。
-
gettext.
dgettext
(domain, message)¶ Like类似于gettext()
, but look the message up in the specified domain.gettext()
,但在指定的domain中查找消息。
-
gettext.
ngettext
(singular, plural, n)¶ Like像gettext()
, but consider plural forms.gettext()
,但考虑复数形式。If a translation is found, apply the plural formula to n, and return the resulting message (some languages have more than two plural forms).如果找到了翻译,请将复数公式应用于n,并返回结果消息(某些语言有两种以上的复数形式)。If no translation is found, return singular if n is 1; return plural otherwise.如果没有找到翻译,如果n为1,则返回单数;否则返回复数。The Plural formula is taken from the catalog header.Plural公式取自目录标题。It is a C or Python expression that has a free variable n; the expression evaluates to the index of the plural in the catalog.它是一个C或Python表达式,它有一个自由变量n;表达式计算为目录中复数的索引。See the GNU gettext documentation for the precise syntax to be used in有关po文件中使用的精确语法以及各种语言的公式,请参阅GNU gettext文档。.po
files and the formulas for a variety of languages.
-
gettext.
dngettext
(domain, singular, plural, n)¶ Like类似于ngettext()
, but look the message up in the specified domain.ngettext()
,但在指定的domain中查找消息。
-
gettext.
pgettext
(context, message)¶
-
gettext.
dpgettext
(domain, context, message)¶
-
gettext.
npgettext
(context, singular, plural, n)¶
-
gettext.
dnpgettext
(domain, context, singular, plural, n)¶ Similar to the corresponding functions without the类似于前缀中没有p的相应函数(即p
in the prefix (that is,gettext()
,dgettext()
,ngettext()
,dngettext()
), but the translation is restricted to the given message context.gettext()
、dgettext()
、ngettext()
、dngettext()
),但转换仅限于给定的消息上下文。New in version 3.8.版本3.8中新增。
-
gettext.
lgettext
(message)¶
-
gettext.
ldgettext
(domain, message)¶
-
gettext.
lngettext
(singular, plural, n)¶
-
gettext.
ldngettext
(domain, singular, plural, n)¶ Equivalent to the corresponding functions without the等效于没有l
prefix (gettext()
,dgettext()
,ngettext()
anddngettext()
), but the translation is returned as a byte string encoded in the preferred system encoding if no other encoding was explicitly set withbind_textdomain_codeset()
.l
前缀的相应函数(gettext()
、dgettext()
、ngettext()
和dngettext()
,但如果没有使用bind_textdomain_codeset()
显式设置其他编码,则转换将作为首选系统编码中编码的字节字符串返回。Warning
These functions should be avoided in Python 3, because they return encoded bytes.在Python 3中应该避免使用这些函数,因为它们返回编码字节。It’s much better to use alternatives which return Unicode strings instead, since most Python applications will want to manipulate human readable text as strings instead of bytes.最好使用返回Unicode字符串的替代方法,因为大多数Python应用程序都希望将人类可读的文本作为字符串而不是字节来处理。Further, it’s possible that you may get unexpected Unicode-related exceptions if there are encoding problems with the translated strings.此外,如果翻译的字符串存在编码问题,则可能会出现意外的Unicode相关异常。Deprecated since version 3.8, removed in version 3.10.从3.8版起已弃用,在3.10版中删除。
Note that GNU gettext also defines a 请注意,GNU gettext还定义了一个dcgettext()
method, but this was deemed not useful and so it is currently unimplemented.dcgettext()
方法,但这被认为是无用的,因此目前尚未实现。
Here’s an example of typical usage for this API:以下是此API的典型用法示例:
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print(_('This is a translatable string.'))
Class-based API基于类的API¶
The class-based API of the 与GNU gettext
module gives you more flexibility and greater convenience than the GNU gettext API. gettext
API相比,gettext模块的基于类的API为您提供了更大的灵活性和更大的便利性。It is the recommended way of localizing your Python applications and modules. 这是本地化Python应用程序和模块的推荐方法。gettext
defines a GNUTranslations
class which implements the parsing of GNU .mo
format files, and has methods for returning strings. gettext
定义了一个GNUTranslations
类,它实现了GNU.mo
格式文件的解析,并具有返回字符串的方法。Instances of this class can also install themselves in the built-in namespace as the function 该类的实例也可以将自身安装在内置命名空间中,作为函数_()
._()
。
-
gettext.
find
(domain, localedir=None, languages=None, all=False)¶ This function implements the standard此函数实现标准的.mo
file search algorithm..mo
文件搜索算法。It takes a domain, identical to what它使用一个domain,与textdomain()
takes.textdomain()
使用的域相同。Optional localedir is as in可选localedir与bindtextdomain()
.bindtextdomain()
相同。Optional languages is a list of strings, where each string is a language code.可选languages是字符串列表,其中每个字符串都是语言代码。If localedir is not given, then the default system locale directory is used.如果未指定localedir,则使用默认的系统区域设置目录。2If languages is not given, then the following environment variables are searched:如果未指定语言,则搜索以下环境变量:LANGUAGE
,LC_ALL
,LC_MESSAGES
, andLANG
.LANGUAGE
、LC_ALL
、LC_MESSAGES
和LANG
。The first one returning a non-empty value is used for the languages variable.第一个返回非空值的变量用于languages变量。The environment variables should contain a colon separated list of languages, which will be split on the colon to produce the expected list of language code strings.环境变量应包含一个以冒号分隔的语言列表,该列表将在冒号上拆分,以生成预期的语言代码字符串列表。find()
then expands and normalizes the languages, and then iterates through them, searching for an existing file built of these components:find()
然后展开并规范语言,然后遍历它们,搜索由这些组件构建的现有文件:localedir/language/LC_MESSAGES/domain.mo
The first such file name that exists is returned byfind()
.find()
返回第一个这样的文件名。If no such file is found, thenNone
is returned.If all is given, it returns a list of all file names, in the order in which they appear in the languages list or the environment variables.如果给定all,它将返回所有文件名的列表,按它们在语言列表或环境变量中的显示顺序排列。
-
gettext.
translation
(domain, localedir=None, languages=None, class_=None, fallback=False, codeset=None)¶ Return a返回一个基于domain、localedir和languages的*Translations
instance based on the domain, localedir, and languages, which are first passed tofind()
to get a list of the associated.mo
file paths.*Translations
实例,这些实例首先传递给find()
以获取相关.mo
文件路径的列表。Instances with identical缓存具有相同mo文件名的实例。.mo
file names are cached.The actual class instantiated is class_ if provided, otherwise实际实例化的类是class_(如果提供),否则是GNUTranslations
.GNUTranslations
。The class’s constructor must take a single file object argument.类的构造函数必须采用单个文件对象参数。If provided, codeset will change the charset used to encode translated strings in the如果提供,codeset将更改用于在lgettext()
andlngettext()
methods.lgettext()
和lngettext()
方法中编码转换字符串的字符集。If multiple files are found, later files are used as fallbacks for earlier ones.如果找到多个文件,则后面的文件将用作前面文件的回退。To allow setting the fallback,为了允许设置回退,copy.copy()
is used to clone each translation object from the cache; the actual instance data is still shared with the cache.copy.copy()
用于从缓存中克隆每个翻译对象;实际实例数据仍然与缓存共享。If no如果找不到.mo
file is found, this function raisesOSError
if fallback is false (which is the default), and returns aNullTranslations
instance if fallback is true..mo
文件,则如果回退为false
(这是默认值),此函数将引发OSError
,如果回退为true
,则返回NullTranslations
实例。Deprecated since version 3.8, removed in version 3.10:从3.8版开始弃用,在3.10版中删除:The codeset parameter.codeset参数。
-
gettext.
install
(domain, localedir=None, codeset=None, names=None)¶ This installs the function这将基于传递给函数_()
in Python’s builtins namespace, based on domain, localedir, and codeset which are passed to the functiontranslation()
.translation()
的domain、localedir和codeset,在Python的内置命名空间中安装函数_()
。For the names parameter, please see the description of the translation object’s对于names参数,请参阅翻译对象的install()
method.install()
方法的描述。As seen below, you usually mark the strings in your application that are candidates for translation, by wrapping them in a call to the如下图所示,通常通过将字符串包装在对_()
function, like this:_()
函数的调用中来标记应用程序中的候选字符串,如下所示:print(_('This string will be translated.'))
For convenience, you want the为了方便起见,您希望将_()
function to be installed in Python’s builtins namespace, so it is easily accessible in all modules of your application._()
函数安装在Python的内置命名空间中,以便可以在应用程序的所有模块中轻松访问。Deprecated since version 3.8, removed in version 3.10:自版本3.8起弃用,在版本3.10中删除:The codeset parameter.codeset参数。
The NullTranslations
classNullTranslations
类¶
NullTranslations
classTranslation classes are what actually implement the translation of original source file message strings to translated message strings. 翻译类实际上实现了将原始源文件消息字符串转换为已翻译消息字符串。The base class used by all translation classes is 所有翻译类使用的基类是NullTranslations
; this provides the basic interface you can use to write your own specialized translation classes. NullTranslations
;这提供了基本接口,您可以使用它编写自己的专用翻译类。Here are the methods of 以下是NullTranslations
:NullTranslations
的方法:
-
class
gettext.
NullTranslations
(fp=None)¶ Takes an optional file object fp, which is ignored by the base class.获取一个可选的文件对象fp,该对象被基类忽略。Initializes “protected” instance variables _info and _charset which are set by derived classes, as well as _fallback, which is set through初始化派生类设置的“受保护”实例变量_info和_charset,以及通过add_fallback()
.add_fallback()
设置的_fallback。It then calls然后如果fp不是self._parse(fp)
if fp is notNone
.None
,则调用self._parse(fp)
。-
_parse
(fp)¶ No-op in the base class, this method takes file object fp, and reads the data from the file, initializing its message catalog.在基类中没有op,此方法获取文件对象fp,并从文件中读取数据,初始化其消息目录。If you have an unsupported message catalog file format, you should override this method to parse your format.如果您的邮件目录文件格式不受支持,则应重写此方法以分析您的格式。
-
add_fallback
(fallback)¶ Add fallback as the fallback object for the current translation object.添加fallback作为当前翻译对象的回退对象。A translation object should consult the fallback if it cannot provide a translation for a given message.如果翻译对象无法为给定消息提供翻译,则应咨询回退。
-
gettext
(message)¶ If a fallback has been set, forward如果设置了回退,则将gettext()
to the fallback.gettext()
转发到回退。Otherwise, return message. Overridden in derived classes.否则,返回message。在派生类中重写。
-
ngettext
(singular, plural, n)¶ If a fallback has been set, forward如果设置了回退,则将ngettext()
to the fallback.ngettext()
转发到回退。Otherwise, return singular if n is 1; return plural otherwise.否则,如果n为1,则返回单数;否则返回复数。Overridden in derived classes.在派生类中重写。
-
pgettext
(context, message)¶ If a fallback has been set, forward如果设置了回退,请将pgettext()
to the fallback.pgettext()
转发到回退。Otherwise, return the translated message. Overridden in derived classes.否则,返回翻译的消息。在派生类中重写。New in version 3.8.版本3.8中新增。
-
npgettext
(context, singular, plural, n)¶ If a fallback has been set, forward如果设置了回退,则将npgettext()
to the fallback.npgettext()
转发到回退。Otherwise, return the translated message.否则,返回已翻译的消息。Overridden in derived classes.在派生类中重写。New in version 3.8.版本3.8中新增。
-
lgettext
(message)¶
-
lngettext
(singular, plural, n)¶ Equivalent to等效于gettext()
andngettext()
, but the translation is returned as a byte string encoded in the preferred system encoding if no encoding was explicitly set withset_output_charset()
.gettext()
和ngettext()
,但如果没有使用set_output_charset()
显式设置编码,则转换将作为首选系统编码中编码的字节字符串返回。Overridden in derived classes.在派生类中重写。Warning
These methods should be avoided in Python 3.在Python 3中应该避免使用这些方法。See the warning for the请参见lgettext()
function.lgettext()
函数的警告。Deprecated since version 3.8, removed in version 3.10.从3.8版起已弃用,在3.10版中删除。
-
info
()¶ Return the “protected”返回“protected”_info
variable, a dictionary containing the metadata found in the message catalog file._info
变量,这是一个包含在消息目录文件中找到的元数据的字典。
-
charset
()¶ Return the encoding of the message catalog file.返回消息目录文件的编码。
-
output_charset
()¶ Return the encoding used to return translated messages in返回用于在lgettext()
andlngettext()
.lgettext()
和lngettext()
中返回已翻译消息的编码。Deprecated since version 3.8, removed in version 3.10.从3.8版起已弃用,在3.10版中删除。
-
set_output_charset
(charset)¶ Change the encoding used to return translated messages.更改用于返回已翻译消息的编码。Deprecated since version 3.8, removed in version 3.10.从3.8版起已弃用,在3.10版中删除。
-
install
(names=None)¶ This method installs此方法将gettext()
into the built-in namespace, binding it to_
.gettext()
安装到内置命名空间中,并将其绑定到_
。If the names parameter is given, it must be a sequence containing the names of functions you want to install in the builtins namespace in addition to如果给定了names参数,它必须是一个序列,其中除了_()
._()
之外,还包含要在内置命名空间中安装的函数的名称。Supported names are支持的名称为'gettext'
,'ngettext'
,'pgettext'
,'npgettext'
,'lgettext'
, and'lngettext'
.'gettext'
、'ngettext'
、'pgettext'
、'npgettext'
、'lgettext'
和'lngettext'
。Note that this is only one way, albeit the most convenient way, to make the请注意,这只是使_()
function available to your application._()
函数对应用程序可用的一种方式,尽管是最方便的方式。Because it affects the entire application globally, and specifically the built-in namespace, localized modules should never install因为它会全局影响整个应用程序,特别是内置的命名空间,所以本地化模块不应该安装_()
._()
。Instead, they should use this code to make相反,他们应该使用以下代码使_()
available to their module:_()
可用于其模块:import gettext
t = gettext.translation('mymodule', ...)
_ = t.gettextThis puts这将_()
only in the module’s global namespace and so only affects calls within this module._()
放在模块的全局命名空间中,因此只影响此模块内的调用。Changed in version 3.8:版本3.8中更改:Added添加了'pgettext'
and'npgettext'
.'pgettext'
和'npgettext'
。
-
The GNUTranslations
classGNUTranslations
类¶
GNUTranslations
classThe gettext
module provides one additional class derived from NullTranslations
: GNUTranslations
. gettext
模块提供了一个从NullTranslations
派生的附加类:GNUTranslations
。This class overrides 该类重写_parse()
to enable reading GNU gettext format .mo
files in both big-endian and little-endian format._parse()
,以允许读取大端和小端格式的GNU gettext格式.mo
文件。
GNUTranslations
parses optional metadata out of the translation catalog. 从翻译目录中解析可选元数据。It is convention with GNU gettext to include metadata as the translation for the empty string. GNUgettext的惯例是将元数据作为空字符串的翻译。This metadata is in RFC 822-style 此元数据采用RFC 822样式的键:值对,并应包含key: value
pairs, and should contain the Project-Id-Version
key. Project-Id-Version
键。If the key 如果找到键Content-Type
is found, then the charset
property is used to initialize the “protected” _charset
instance variable, defaulting to None
if not found. Content-Type
,则使用charset
属性初始化“protected”_charset
实例变量,如果找不到,则默认为None
。If the charset encoding is specified, then all message ids and message strings read from the catalog are converted to Unicode using this encoding, else ASCII is assumed.如果指定了字符集编码,则使用此编码将从目录中读取的所有消息ID和消息字符串转换为Unicode,否则假定为ASCII。
Since message ids are read as Unicode strings too, all 由于消息ID也是作为Unicode字符串读取的,所以所有的*gettext()
methods will assume message ids as Unicode strings, not byte strings.*gettext()
方法都将消息ID假定为Unicode字符串,而不是字节字符串。
The entire set of key/value pairs are placed into a dictionary and set as the “protected” 整个键/值对集被放入字典中,并设置为“protected”_info
instance variable._info
实例变量。
If the 如果.mo
file’s magic number is invalid, the major version number is unexpected, or if other problems occur while reading the file, instantiating a GNUTranslations
class can raise OSError
..mo
文件的幻数无效,主要版本号是意外的,或者如果在读取文件时出现其他问题,实例化GNUTranslations
类可能会引发OSError
。
-
class
gettext.
GNUTranslations
¶ The following methods are overridden from the base class implementation:从基类实现重写以下方法:-
gettext
(message)¶ Look up the message id in the catalog and return the corresponding message string, as a Unicode string.在目录中查找messageid,并以Unicode字符串的形式返回相应的消息字符串。If there is no entry in the catalog for the message id, and a fallback has been set, the look up is forwarded to the fallback’s如果目录中没有messageid的条目,并且设置了回退,则查找将转发到回退的gettext()
method.gettext()
方法。Otherwise, the message id is returned.否则,将返回messageid。
-
ngettext
(singular, plural, n)¶ Do a plural-forms lookup of a message id.对消息id进行多种形式的查找。singular is used as the message id for purposes of lookup in the catalog, while n is used to determine which plural form to use.单数用作在目录中查找的消息id,而n用于确定要使用的复数形式。The returned message string is a Unicode string.返回的消息字符串是Unicode字符串。If the message id is not found in the catalog, and a fallback is specified, the request is forwarded to the fallback’s如果在目录中找不到消息id,并且指定了回退,则将请求转发到回退的ngettext()
method.ngettext()
方法。Otherwise, when n is 1 singular is returned, and plural is returned in all other cases.否则,当n为1时,返回单数,在所有其他情况下返回复数。Here is an example:下面是一个例子:n = len(os.listdir('.'))
cat = GNUTranslations(somefile)
message = cat.ngettext(
'There is %(num)d file in this directory',
'There are %(num)d files in this directory',
n) % {'num': n}
-
pgettext
(context, message)¶ Look up the context and message id in the catalog and return the corresponding message string, as a Unicode string.在目录中查找context和messageid,并以Unicode字符串的形式返回相应的消息字符串。If there is no entry in the catalog for the message id and context, and a fallback has been set, the look up is forwarded to the fallback’s如果目录中没有messageid和context的条目,并且设置了回退,则查找将转发到回退的pgettext()
method.pgettext()
方法。Otherwise, the message id is returned.否则,将返回messageid。New in version 3.8.版本3.8中新增。
-
npgettext
(context, singular, plural, n)¶ Do a plural-forms lookup of a message id.对消息id进行复数形式查找。singular is used as the message id for purposes of lookup in the catalog, while n is used to determine which plural form to use.单数用作在目录中查找的消息id,而n用于确定要使用的复数形式。If the message id for context is not found in the catalog, and a fallback is specified, the request is forwarded to the fallback’s如果在目录中找不到上下文的消息id,并且指定了回退,则将请求转发到回退的npgettext()
method.npgettext()
方法。Otherwise, when n is 1 singular is returned, and plural is returned in all other cases.否则,当n为1时,返回单数,在所有其他情况下返回复数。New in version 3.8.版本3.8中新增。
-
lgettext
(message)¶
-
lngettext
(singular, plural, n)¶ Equivalent to等效于gettext()
andngettext()
, but the translation is returned as a byte string encoded in the preferred system encoding if no encoding was explicitly set withset_output_charset()
.gettext()
和ngettext()
,但如果没有使用set_output_charset()
显式设置编码,则转换将作为首选系统编码中编码的字节字符串返回。Warning
These methods should be avoided in Python 3.在Python 3中应该避免使用这些方法。See the warning for the请参见lgettext()
function.lgettext()
函数的警告。Deprecated since version 3.8, removed in version 3.10.从3.8版起已弃用,在3.10版中删除。
-
Solaris message catalog supportSolaris消息目录支持¶
The Solaris operating system defines its own binary Solaris操作系统定义了自己的二进制.mo
file format, but since no documentation can be found on this format, it is not supported at this time..mo
文件格式,但由于找不到有关该格式的文档,因此目前不支持该格式。
The Catalog constructor目录构造函数¶
GNOME uses a version of the GNOME使用了詹姆斯·亨斯特里奇(James Henstridge)的gettext
module by James Henstridge, but this version has a slightly different API. gettext
模块版本,但该版本的API略有不同。Its documented usage was:其使用记录如下:
import gettext
cat = gettext.Catalog(domain, localedir)
_ = cat.gettext
print(_('hello world'))
For compatibility with this older module, the function 为了与此旧模块兼容,函数Catalog()
is an alias for the translation()
function described above.Catalog()
是上述translation()
函数的别名。
One difference between this module and Henstridge’s: his catalog objects supported access through a mapping API, but this appears to be unused and so is not currently supported.这个模块和亨斯特里奇的一个区别是:他的目录对象支持通过映射API进行访问,但这似乎是未使用的,因此目前不支持。
Internationalizing your programs and modules国际化您的程序和模块¶
Internationalization (I18N) refers to the operation by which a program is made aware of multiple languages. 国际化(I18N)是指使程序了解多种语言的操作。Localization (L10N) refers to the adaptation of your program, once internationalized, to the local language and cultural habits. 本地化(L10N)指的是一旦国际化,您的程序将适应当地语言和文化习惯。In order to provide multilingual messages for your Python programs, you need to take the following steps:为了为Python程序提供多语言消息,您需要执行以下步骤:
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 translatedgettext
模块,以便正确翻译消息字符串
In order to prepare your code for I18N, you need to look at all the strings in your files. 为了准备I18N的代码,您需要查看文件中的所有字符串。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')
with open(filename, 'w') as fp:
fp.write(message)
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.
There are a few tools to extract the strings meant for translation. The original GNU gettext only supported C or C++ source code but its extended version xgettext scans code written in a number of languages, including Python, to find strings marked as translatable. Babel is a Python internationalization library that includes a pybabel
script to extract and compile message catalogs. François Pinard’s program called xpot does a similar job and is available as part of his po-utils package.
(Python also includes pure-Python versions of these programs, called pygettext.py and msgfmt.py; some Python distributions will install them for you. pygettext.py is similar to xgettext, but only understands Python source code and cannot handle other programming languages such as C or C++. pygettext.py supports a command-line interface similar to xgettext; for details on its use, run pygettext.py --help
. msgfmt.py is binary compatible with GNU msgfmt. With these two programs, you may not need the GNU gettext package to internationalize your Python applications.)
xgettext, pygettext, and similar tools generate .po
files that are message catalogs. They are structured human-readable files that contain every marked string in the source code, along with a placeholder for the translated versions of these strings.
Copies of these .po
files are then handed over to the individual human translators who write translations for every supported natural language. They send back the completed language-specific versions as a <language-name>.po
file that’s compiled into a machine-readable .mo
binary catalog file using the msgfmt program. The .mo
files are used by the gettext
module for the actual translation processing at run-time.
How you use the 如何在代码中使用gettext
module in your code depends on whether you are internationalizing a single module or your entire application. gettext
模块取决于您是国际化单个模块还是国际化整个应用程序。The next two sections will discuss each case.下两节将讨论每种情况。
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.您不应该使用GNU gettext API,而是使用基于类的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. .mo
文件以GNU gettext格式驻留在/usr/share/locate
中。Here’s what you would put at the top of your module:以下是您将放在模块顶部的内容:
import gettext
t = gettext.translation('spam', '/usr/share/locale')
_ = t.gettext
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, you can pass it into the 如果需要设置区域设置目录,可以将其传递到install()
function:install()
函数中:
import gettext
gettext.install('myapplication', '/usr/share/locale')
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()
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.animals
列表中的字符串标记为可翻译,但在打印之前,您实际上不想翻译它们。
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). _()
定义(直到del
命令)。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 gettext program, because the parameter is not a string literal._()
不会将“a”标识为可翻译到gettext程序,因为该参数不是字符串文本。
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_()
, which won’t conflict with any definition of _()
. N_()
标记可翻译字符串,这不会与_()
的任何定义冲突。However, you will need to teach your message extraction program to look for translatable strings marked with 然而,您需要教您的消息提取程序查找标记为N_()
. N_()
的可翻译字符串。xgettext, pygettext, xgettext、pygettext、pybabel extract和xpot都通过使用pybabel extract
, and xpot all support this through the use of the -k
command-line switch. -k
命令行开关支持这一点。The choice of 这里N_()
here is totally arbitrary; it could have just as easily been MarkThisStringForTranslation()
.N_()
的选择是完全任意的;它可以像MarkThisStringForTranslation()
一样简单。
Acknowledgements致谢¶
The following people contributed code, feedback, design suggestions, previous implementations, and valuable experience to the creation of this module:以下人员为本模块的创建提供了代码、反馈、设计建议、以前的实现和宝贵的经验:
Peter Funk
James Henstridge
Juan David Ibáñez Palomar
Marc-André Lemburg
Martin von Löwis
François Pinard
Barry Warsaw
Gustavo Niemeyer
Footnotes
- 1
The default locale directory is system dependent; for example, on RedHat Linux it is
/usr/share/locale
, but on Solaris it is/usr/lib/locale
. Thegettext
module does not try to support these system dependent defaults; instead its default issys.base_prefix/share/locale
(seesys.base_prefix
). For this reason, it is always best to callbindtextdomain()
with an explicit absolute path at the start of your application.- 2
See the footnote for
bindtextdomain()
above.