gettext --- 倚蚀語囜際化サヌビス¶

゜ヌスコヌド: Lib/gettext.py


The gettext module provides internationalization (I18N) and localization (L10N) services for your Python modules and applications. It supports both the GNU gettext message catalog API and a higher level, class-based API that may be more appropriate for Python files. 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.

ここでは Python のモゞュヌルやアプリケヌションを地域化するためのいく぀かのヒントも提䟛しおいたす。

GNU gettext API¶

The gettext module defines the following API, which is very similar to the GNU gettext API. If you use this API you will affect the translation of your entire application globally. 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.

gettext.bindtextdomain(domain, localedir=None)¶

Bind the domain to the locale directory 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 variables LANGUAGE, LC_ALL, LC_MESSAGES, and LANG respectively.

localedir が省略されるか None の堎合、珟圚 domain に察応付けられおいるロケヌルディレクトリが返されたす。 [1]

gettext.textdomain(domain=None)¶

珟圚のグロヌバルドメむンを倉曎したり調べたりしたす。 domain が None の堎合、珟圚のグロヌバルドメむンが返されたす。それ以倖の堎合には、グロヌバルドメむンに domain を蚭定し、その蚭定されたグロヌバルドメむンを返したす。

gettext.gettext(message, /)¶

Return the localized translation of message, based on the current global domain, language, and locale directory. This function is usually aliased as _() in the local namespace (see examples below).

gettext.dgettext(domain, message, /)¶

gettext() ず同様ですが、指定された domain からメッセヌゞを探したす。

gettext.ngettext(singular, plural, n, /)¶

gettext() ず同様ですが、耇数圢を考慮しおいたす。 翻蚳が芋぀かった堎合、耇数圢の遞択公匏を n に適甚し、その結果埗られたメッセヌゞを返したす (蚀語によっおは二぀以䞊の耇数圢がありたす)。 翻蚳が芋぀からなかった堎合、 n が 1 なら singular を返したす; そうでない堎合 plural を返したす。

耇数圢の遞択公匏はカタログのヘッダから取埗されたす。 遞択公匏は自由倉数 n を持぀ C たたは Python の匏です; その匏の評䟡結果はカタログにある耇数圢のむンデックスになりたす。 .po ファむルで甚いられる詳现な文法ず、様々な蚀語における遞択公匏に぀いおは GNU gettext ドキュメント を参照しおください。

gettext.dngettext(domain, singular, plural, n, /)¶

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 in the prefix (that is, gettext(), dgettext(), ngettext(), dngettext()), but the translation is restricted to the given message context.

Added in version 3.8.

Note that GNU gettext also defines a dcgettext() method, but this was deemed not useful and so it is currently unimplemented.

以䞋にこの API の兞型的な䜿甚法を瀺したす:

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print(_('This is a translatable string.'))

クラス圢匏の API¶

The class-based API of the gettext module gives you more flexibility and greater convenience than the GNU gettext API. It is the recommended way of localizing your Python applications and modules. gettext defines a GNUTranslations class which implements the parsing of GNU .mo format files, and has methods for returning strings. 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)¶

この関数は暙準的な .mo ファむル怜玢アルゎリズムを実装しおいたす。 textdomain() ず同じく、 domain を匕数にずりたす。オプションの localedir は bindtextdomain() ず同じです。たたオプションの languages は文字列を列挙したリストで、各文字列は蚀語コヌドを衚したす。

localedir が䞎えられおいない堎合、暙準のシステムロケヌルディレクトリが䜿われたす。 [2] languages が䞎えられなかった堎合、以䞋の環境倉数: LANGUAGE 、 LC_ALL 、 LC_MESSAGES 、および LANG が怜玢されたす。空でない倀を返した最初の候補が languages 倉数ずしお䜿われたす。この環境倉数は蚀語名をコロンで分かち曞きしたリストを含んでいなければなりたせん。 find() はこの文字列をコロンで分割し、蚀語コヌドの候補リストを生成したす。

find() は次に蚀語コヌドを展開および正芏化し、リストの各芁玠に぀いお、以䞋のパス構成:

localedir/language/LC_MESSAGES/domain.mo

からなる実圚するファむルの探玢を反埩的に行いたす。 find() は䞊蚘のような実圚するファむルで最初に芋぀かったものを返したす。該圓するファむルが芋぀からなかった堎合、 None が返されたす。 all が䞎えられおいれば、党ファむル名のリストが蚀語リストたたは環境倉数で指定されおいる順番に䞊べられたものを返したす。

gettext.translation(domain, localedir=None, languages=None, class_=None, fallback=False)¶

Return a *Translations instance based on the domain, localedir, and languages, which are first passed to find() to get a list of the associated .mo file paths. Instances with identical .mo file names are cached. The actual class instantiated is class_ if provided, otherwise GNUTranslations. The class's constructor must take a single file object argument.

耇数の .mo ファむルがあった堎合、埌ろのファむルは前のファむルのフォヌルバックずしお利甚されたす。 フォヌルバックの蚭定のために、 copy.copy() を䜿いキャッシュから翻蚳オブゞェクトを耇補したす; こうするこずで、実際のむンスタンスデヌタはキャッシュのものず共有されたたたになりたす。

.mo ファむルが芋぀からなかった堎合、 fallback が停 (デフォルト倀) ならこの関数は OSError を送出し、 fallback が真なら NullTranslations むンスタンスが返されたす。

バヌゞョン 3.3 で倉曎: 以前は IOError が送出されたした; それは珟圚 OSError の゚むリアスです。

バヌゞョン 3.11 で倉曎: codeset parameter is removed.

gettext.install(domain, localedir=None, *, names=None)¶

This installs the function _() in Python's builtins namespace, based on domain and localedir which are passed to the function translation().

names パラメヌタに぀いおは、翻蚳オブゞェクトの 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.

バヌゞョン 3.11 で倉曎: names is now a keyword-only parameter.

NullTranslations クラス¶

翻蚳クラスは、元の゜ヌスファむル䞭のメッセヌゞ文字列から翻蚳されたメッセヌゞ文字列ぞの倉換凊理が実際に実装されおいるクラスです。 党おの翻蚳クラスで基底クラスずしお䜿われおいるクラスが NullTranslations です; このクラスは、独自の翻蚳クラスを実装するのに䜿える基本的なむンタヌフェヌスを提䟛しおいたす。 以䞋に NullTranslations のメ゜ッドを瀺したす:

class gettext.NullTranslations(fp=None)¶

オプションの ファむルオブゞェクト fp を取りたす。この匕数は基底クラスでは無芖されたす。このメ゜ッドは "保護された (protected)" むンスタンス倉数 _info および _charset を初期化したす。これらの倉数の倀は掟生クラスで蚭定するこずができたす。同様に _fallback も初期化したすが、この倀は add_fallback() で蚭定されたす。その埌、 fp が None でない堎合 self._parse(fp) を呌び出したす。

_parse(fp)¶

基底クラスでは䜕もしない (no-op) ようになっおいたす。このメ゜ッドの圹割はファむルオブゞェクト fp を匕数に取り、ファむルからデヌタを読み出し、メッセヌゞカタログを初期化するこずです。サポヌトされおいないメッセヌゞカタログ圢匏を䜿っおいる堎合、その圢匏を解釈するためにはこのメ゜ッドを䞊曞きしなくおはなりたせん。

add_fallback(fallback)¶

fallback を珟圚の翻蚳オブゞェクトの代替オブゞェクトずしお远加したす。翻蚳オブゞェクトが䞎えられたメッセヌゞに察しお翻蚳メッセヌゞを提䟛できない堎合、この代替オブゞェクトに問い合わせるこずになりたす。

gettext(message, /)¶

フォヌルバックが蚭定されおいる堎合、フォヌルバックの gettext() に凊理を移譲したす。 そうでない堎合、匕数ずしお受け取った message を返したす。 掟生クラスで䞊曞きするメ゜ッドです。

ngettext(singular, plural, n, /)¶

フォヌルバックが蚭定されおいる堎合、フォヌルバックの ngettext() に凊理を移譲したす。 そうでない堎合、 n が 1 なら singular を返したす; それ以倖なら plural を返したす。 掟生クラスで䞊曞きするメ゜ッドです。

pgettext(context, message, /)¶

代替オブゞェクトが蚭定されおいる堎合、 pgettext() を代替オブゞェクトに転送したす。そうでない堎合、翻蚳されたメッセヌゞを返したす。掟生クラスで䞊曞きするメ゜ッドです。

Added in version 3.8.

npgettext(context, singular, plural, n, /)¶

代替オブゞェクトが蚭定されおいる堎合、 npgettext() を代替オブゞェクトに転送したす。そうでない堎合、翻蚳されたメッセヌゞを返したす。掟生クラスで䞊曞きするメ゜ッドです。

Added in version 3.8.

info()¶

Return a dictionary containing the metadata found in the message catalog file.

charset()¶

メッセヌゞカタログファむルの゚ンコヌディングを返したす。

install(names=None)¶

このメ゜ッドは 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 _(). Supported names are 'gettext', 'ngettext', 'pgettext', and 'npgettext'.

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

This puts _() only in the module's global namespace and so only affects calls within this module.

バヌゞョン 3.8 で倉曎: 'pgettext' ず 'npgettext' が远加されたした。

GNUTranslations クラス¶

The gettext module provides one additional class derived from NullTranslations: GNUTranslations. This class overrides _parse() to enable reading GNU gettext format .mo files in both big-endian and little-endian format.

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. This metadata is in RFC 822-style key: value pairs, and should contain the Project-Id-Version key. 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. 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.

Since message ids are read as Unicode strings too, all *gettext() methods will assume message ids as Unicode strings, not byte strings.

The entire set of key/value pairs are placed into a dictionary and set as the "protected" _info instance variable.

.mo ファむルのマゞックナンバヌが䞍正な堎合や、メゞャヌバヌゞョン番号が予期されないものの堎合、あるいはその他の問題がファむルの読み出し䞭に発生した堎合、 GNUTranslations クラスのむンスタンス化で OSError が送出されるこずがありたす。

class gettext.GNUTranslations¶

以䞋のメ゜ッドは基底クラスの実装からオヌバラむドされおいたす:

gettext(message, /)¶

カタログから message id を怜玢しお、察応するメッセヌゞ文字列を Unicode で゚ンコヌドしお返したす。 message id に察応する゚ントリがカタログに存圚せず、フォヌルバックが蚭定されおいる堎合、怜玢凊理をフォヌルバックの gettext() メ゜ッドに移譲したす。 それ以倖の堎合は、 message id 自䜓が返されたす。

ngettext(singular, plural, n, /)¶

メッセヌゞ id に察する耇数圢を怜玢したす。カタログに察する怜玢では singular がメッセヌゞ id ずしお甚いられ、 n にはどの耇数圢を甚いるかを指定したす。返されるメッセヌゞ文字列は Unicode 文字列です。

メッセヌゞ id がカタログ䞭に芋぀からず、フォヌルバックが指定されおいる堎合は、メッセヌゞ怜玢芁求はフォヌルバックの ngettext() メ゜ッドに移譲されたす。 それ以倖の堎合、 n が 1 ならば singular が返され、それ以倖なら plural が返されたす。

以䞋に䟋を瀺したす。:

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, /)¶

カタログから context ず message id を怜玢しお、察応するメッセヌゞ文字列を、 Unicode で゚ンコヌドしお返したす。 message id ず context に察する゚ントリがカタログに存圚せず、フォヌルバックが蚭定されおいる堎合、フォヌルバック怜玢はオブゞェクトの pgettext() メ゜ッドに転送されたす。そうでない堎合、 message id 自䜓が返されたす。

Added in version 3.8.

npgettext(context, singular, plural, n, /)¶

メッセヌゞ id に察する耇数圢を怜玢したす。カタログに察する怜玢では singular がメッセヌゞ id ずしお甚いられ、 n にはどの耇数圢を甚いるかを指定したす。

context に察するメッセヌゞ id がカタログ䞭に芋぀からず、フォヌルバックオブゞェクトが指定されおいる堎合、メッセヌゞ怜玢芁求はフォヌルバックオブゞェクトの npgettext() メ゜ッドに転送されたす。そうでない堎合、 n が 1 ならば singular が返され、それ以倖に察しおは plural が返されたす。

Added in version 3.8.

Solaris メッセヌゞカタログ機構のサポヌト¶

Solaris オペレヌティングシステムでは、独自の .mo バむナリファむル圢匏を定矩しおいたすが、この圢匏に関するドキュメントが手に入らないため、珟時点ではサポヌトされおいたせん。

Catalog コンストラクタ¶

GNOME uses a version of the gettext module by James Henstridge, but this version has a slightly different 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.

このモゞュヌルず Henstridge のバヌゞョンずの間には䞀぀盞違点がありたす: 圌のカタログオブゞェクトはマップ型の API を介したアクセスがサポヌトされおいたしたが、この API は䜿われおいないらしく、珟圚はサポヌトされおいたせん。

プログラムやモゞュヌルを囜際化する¶

囜際化 (I18N, I-nternationalizatio-N) ずは、プログラムを耇数の蚀語に察応させる操䜜を指したす。地域化 (L10N, L-ocalizatio-N) ずは、すでに囜際化されおいるプログラムを特定地域の蚀語や文化的な事情に察応させるこずを指したす。Python プログラムに倚蚀語メッセヌゞ機胜を远加するには、以䞋の手順を螏む必芁がありたす:

  1. プログラムやモゞュヌルで翻蚳察象ずする文字列に特殊なマヌクを぀けお準備したす

  2. マヌクづけをしたファむルに䞀連のツヌルを走らせ、生のメッセヌゞカタログを生成したす

  3. 特定の蚀語ぞのメッセヌゞカタログの翻蚳を䜜成したす

  4. 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')
with open(filename, 'w') as fp:
    fp.write(message)

この䟋では、文字列 'writing a log message' が翻蚳察象候補ずしおマヌク付けされおおり、文字列 'mylog.txt' および 'w' はされおいたせん。

翻蚳察象の文字列を抜出するツヌルもありたす。 オリゞナルの GNU gettext は C ず C++ の゜ヌスコヌドしかサポヌトしたせんが、拡匵版の xgettext は Python を含めた倚くの蚀語で曞かれたコヌドを読み取り、翻蚳できる文字列を発芋したす。 Babel は Python の囜際化ラむブラリで、翻蚳文字列の抜出ずメッセヌゞカタログのコンパむルを行う pybabel スクリプトがありたす。 François Pinard が開発した xpot ず呌ばれるプログラムは同じような凊理を行え、圌の po-utils package の䞀郚ずしお利甚可胜です。

(Python には pygettext.py および msgfmt.py ずいう名前の pure-Python 版プログラムもありたす; これをむンストヌルしおくれる Python ディストリビュヌションもありたす。 pygettext.py は xgettext に䌌たプログラムですが Python の゜ヌスコヌドしか理解できず、 C や C++ のような他のプログラミング蚀語を扱えたせん。 pygettext.py は xgettext ず同様のコマンドラむンむンタヌフェヌスをサポヌトしおいたす; 詳しい䜿い方に぀いおは pygettext.py --help ず実行しおください。 msgfmt.py は GNU msgfmt ずバむナリ互換性がありたす。 この2぀のプログラムがあれば、 GNU gettext パッケヌゞを䜿わずに Python アプリケヌションを囜際化できるでしょう。)

xgettext や pygettext のようなツヌルは、メッセヌゞカタログである .po ファむルを生成したす。 このファむルは人間が刀読可胜な構造をしおいお、゜ヌスコヌド䞭のマヌクが着けられた文字列ず、その文字列の仮眮きの蚳文が䞀緒に曞き蟌たれおいたす。

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. The next two sections will discuss each case.

モゞュヌルを地域化する¶

モゞュヌルを地域化する堎合、グロヌバルな倉曎、䟋えば組み蟌み名前空間ぞの倉曎を行わないように泚意しなければなりたせん。GNU gettext API ではなく、クラス圢匏の API を䜿うべきです。

仮に察象のモゞュヌル名を "spam" ずし、モゞュヌルの各蚀語における翻蚳が収められた .mo ファむルが /usr/share/locale に GNU gettext 圢匏で眮かれおいるずしたす。この堎合、モゞュヌルの最初で以䞋のようにしたす:

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

アプリケヌションを地域化する¶

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.

単玔な堎合では、単に以䞋の短いコヌドをアプリケヌションの䞻ドラむバファむルに远加するだけです:

import gettext
gettext.install('myapplication')

ロケヌルの蟞曞を蚭定する必芁がある堎合、install() 関数に枡すこずが出来たす:

import gettext
gettext.install('myapplication', '/usr/share/locale')

動䜜䞭 (on the fly) に蚀語を切り替える¶

倚くの蚀語を同時にサポヌトする必芁がある堎合、耇数の翻蚳むンスタンスを生成しお、䟋えば以䞋のコヌドのように、むンスタンスを明瀺的に切り替えおもかたいたせん。:

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()

翻蚳凊理の遅延解決¶

コヌドを曞く䞊では、ほずんどの状況で文字列はコヌドされた堎所で翻蚳されたす。しかし堎合によっおは、翻蚳察象ずしお文字列をマヌクはするが、その埌実際に翻蚳が行われるように遅延させる必芁が生じたす。叀兞的な䟋は以䞋のようなコヌトです:

animals = ['mollusk',
           'albatross',
           'rat',
           'penguin',
           'python', ]
# ...
for a in animals:
    print(a)

ここで、リスト animals 内の文字列は翻蚳察象ずしおマヌクはしたいが、文字列が出力されるたで実際に翻蚳を行うのは避けたいずしたす。

こうした状況を凊理する䞀぀の方法を以䞋に瀺したす:

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 gettext program, because the parameter is not a string literal.

もう䞀぀の凊理法は、以䞋の䟋のようなやり方です:

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 _(). However, you will need to teach your message extraction program to look for translatable strings marked with N_(). xgettext, pygettext, pybabel extract, and xpot all support this through the use of the -k command-line switch. The choice of N_() here is totally arbitrary; it could have just as easily been MarkThisStringForTranslation().

謝蟞¶

以䞋の人々が、このモゞュヌルのコヌド、フィヌドバック、蚭蚈に関する助蚀、過去の実装、そしお有益な経隓談による貢献をしおくれたした:

  • Peter Funk

  • James Henstridge

  • Juan David Ibáñez Palomar

  • Marc-André Lemburg

  • Martin von Löwis

  • François Pinard

  • Barry Warsaw

  • Gustavo Niemeyer

脚泚