mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
79 lines
65 KiB
HTML
79 lines
65 KiB
HTML
<div class="body" role="main"><div class="section" id="module-gettext"><h1><span class="yiyi-st" id="yiyi-10">23.1. <a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a> - 多语言国际化服务</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/gettext.py">Lib/gettext.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块为您的Python模块和应用程序提供了国际化(I18N)和本地化(L10N)服务。</span><span class="yiyi-st" id="yiyi-13">它支持GNU <code class="docutils literal"><span class="pre">gettext</span></code>消息目录API和更高级别的基于类的API,可能更适合Python文件。</span><span class="yiyi-st" id="yiyi-14">下面描述的界面允许您以一种自然语言编写模块和应用程序消息,并提供用不同自然语言运行的翻译消息目录。</span></p><p><span class="yiyi-st" id="yiyi-15">还给出了一些本地化您的Python模块和应用程序的提示。</span></p><div class="section" id="gnu-gettext-api"><h2><span class="yiyi-st" id="yiyi-16">23.1.1. </span><span class="yiyi-st" id="yiyi-17">GNU <strong class="program">gettext</strong> API </span></h2><p><span class="yiyi-st" id="yiyi-18"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块定义了以下API,它非常类似于GNU <strong class="program">gettext</strong> API。</span><span class="yiyi-st" id="yiyi-19">如果您使用此API,您将影响整个应用程序的全球翻译。</span><span class="yiyi-st" id="yiyi-20">通常这是你想要的,如果你的应用程序是单语,选择的语言取决于你的用户的语言环境。</span><span class="yiyi-st" id="yiyi-21">如果要本地化Python模块,或者如果应用程序需要即时切换语言,则可能需要使用基于类的API。</span></p><dl class="function"><dt id="gettext.bindtextdomain"><span class="yiyi-st" id="yiyi-22"> <code class="descclassname">gettext.</code><code class="descname">bindtextdomain</code><span class="sig-paren">(</span><em>domain</em>, <em>localedir=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-23">将<em>域</em>绑定到语言环境目录<em>localedir</em>。</span><span class="yiyi-st" id="yiyi-24">More concretely, <a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a> will look for binary <code class="file docutils literal"><span class="pre">.mo</span></code> files for the given domain using the path (on Unix): <code class="file docutils literal"><span class="pre">localedir/language/LC_MESSAGES/domain.mo</span></code>, where <em>languages</em> is searched for in the environment variables <span class="target" id="index-0"></span><code class="xref std std-envvar docutils literal"><span class="pre">LANGUAGE</span></code>, <span class="target" id="index-1"></span><code class="xref std std-envvar docutils literal"><span class="pre">LC_ALL</span></code>, <span class="target" id="index-2"></span><code class="xref std std-envvar docutils literal"><span class="pre">LC_MESSAGES</span></code>, and <span class="target" id="index-3"></span><code class="xref std std-envvar docutils literal"><span class="pre">LANG</span></code> respectively.</span></p><p><span class="yiyi-st" id="yiyi-25">如果省略<em>localedir</em>或<code class="docutils literal"><span class="pre">None</span></code>,则返回<em>域</em>的当前绑定。</span><span class="yiyi-st" id="yiyi-26"><a class="footnote-reference" href="#id3" id="id1">[1]</a></span></p></dd></dl><dl class="function"><dt id="gettext.bind_textdomain_codeset"><span class="yiyi-st" id="yiyi-27"> <code class="descclassname">gettext.</code><code class="descname">bind_textdomain_codeset</code><span class="sig-paren">(</span><em>domain</em>, <em>codeset=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-28">将<em>域</em>绑定到<em>代码集</em>,更改由<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-func docutils literal"><span class="pre">gettext()</span></code></a>函数系列返回的字符串的编码。</span><span class="yiyi-st" id="yiyi-29">如果省略<em>codeset</em>,则返回当前绑定。</span></p></dd></dl><dl class="function"><dt id="gettext.textdomain"><span class="yiyi-st" id="yiyi-30"> <code class="descclassname">gettext.</code><code class="descname">textdomain</code><span class="sig-paren">(</span><em>domain=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-31">更改或查询当前全局域。</span><span class="yiyi-st" id="yiyi-32">如果<em>域</em>为<code class="docutils literal"><span class="pre">None</span></code>,则返回当前全局域,否则将全局域设置为<em>域</em>,返回。</span></p></dd></dl><dl class="function"><dt id="gettext.gettext"><span class="yiyi-st" id="yiyi-33"> <code class="descclassname">gettext.</code><code class="descname">gettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-34">根据当前的全局域,语言和区域设置目录返回<em>消息</em>的本地化转换。</span><span class="yiyi-st" id="yiyi-35">此函数通常在本地命名空间中以<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>别名(参见下面的示例)。</span></p></dd></dl><dl class="function"><dt id="gettext.lgettext"><span class="yiyi-st" id="yiyi-36"> <code class="descclassname">gettext.</code><code class="descname">lgettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-37">等同于<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-func docutils literal"><span class="pre">gettext()</span></code></a>,但是如果未使用<a class="reference internal" href="#gettext.bind_textdomain_codeset" title="gettext.bind_textdomain_codeset"><code class="xref py py-func docutils literal"><span class="pre">bind_textdomain_codeset()</span></code></a>显式设置其他编码,则会在首选系统编码中返回翻译。</span></p></dd></dl><dl class="function"><dt id="gettext.dgettext"><span class="yiyi-st" id="yiyi-38"> <code class="descclassname">gettext.</code><code class="descname">dgettext</code><span class="sig-paren">(</span><em>domain</em>, <em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-39">像<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-func docutils literal"><span class="pre">gettext()</span></code></a>,但查看指定的<em>域</em>中的消息。</span></p></dd></dl><dl class="function"><dt id="gettext.ldgettext"><span class="yiyi-st" id="yiyi-40"> <code class="descclassname">gettext.</code><code class="descname">ldgettext</code><span class="sig-paren">(</span><em>domain</em>, <em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-41">等同于<a class="reference internal" href="#gettext.dgettext" title="gettext.dgettext"><code class="xref py py-func docutils literal"><span class="pre">dgettext()</span></code></a>,但如果未使用<a class="reference internal" href="#gettext.bind_textdomain_codeset" title="gettext.bind_textdomain_codeset"><code class="xref py py-func docutils literal"><span class="pre">bind_textdomain_codeset()</span></code></a>显式设置其他编码,则会在首选系统编码中返回翻译。</span></p></dd></dl><dl class="function"><dt id="gettext.ngettext"><span class="yiyi-st" id="yiyi-42"> <code class="descclassname">gettext.</code><code class="descname">ngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-43">像<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-func docutils literal"><span class="pre">gettext()</span></code></a>,但是考虑复数形式。</span><span class="yiyi-st" id="yiyi-44">如果找到翻译,则将复数公式应用于<em>n</em>,并返回结果消息(某些语言具有多个复数形式)。</span><span class="yiyi-st" id="yiyi-45">如果未找到翻译,则如果<em>n</em>为1,则返回<em>奇异</em>否则返回<em>多个</em>。</span></p><p><span class="yiyi-st" id="yiyi-46">多个公式取自目录标题。</span><span class="yiyi-st" id="yiyi-47">它是一个C或Python表达式,有一个自由变量<em>n</em>;该表达式求值为目录中的复数的索引。</span><span class="yiyi-st" id="yiyi-48">有关在<code class="file docutils literal"><span class="pre">.po</span></code>文件中使用的精确语法和各种语言的公式,请参见<a class="reference external" href="https://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext文档</a>。</span></p></dd></dl><dl class="function"><dt id="gettext.lngettext"><span class="yiyi-st" id="yiyi-49"> <code class="descclassname">gettext.</code><code class="descname">lngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-50">等同于<a class="reference internal" href="#gettext.ngettext" title="gettext.ngettext"><code class="xref py py-func docutils literal"><span class="pre">ngettext()</span></code></a>,但是如果未使用<a class="reference internal" href="#gettext.bind_textdomain_codeset" title="gettext.bind_textdomain_codeset"><code class="xref py py-func docutils literal"><span class="pre">bind_textdomain_codeset()</span></code></a>显式设置其他编码,则会在首选系统编码中返回翻译。</span></p></dd></dl><dl class="function"><dt id="gettext.dngettext"><span class="yiyi-st" id="yiyi-51"> <code class="descclassname">gettext.</code><code class="descname">dngettext</code><span class="sig-paren">(</span><em>domain</em>, <em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-52">像<a class="reference internal" href="#gettext.ngettext" title="gettext.ngettext"><code class="xref py py-func docutils literal"><span class="pre">ngettext()</span></code></a>,但查看指定的<em>域</em>中的消息。</span></p></dd></dl><dl class="function"><dt id="gettext.ldngettext"><span class="yiyi-st" id="yiyi-53"> <code class="descclassname">gettext.</code><code class="descname">ldngettext</code><span class="sig-paren">(</span><em>domain</em>, <em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-54">等同于<a class="reference internal" href="#gettext.dngettext" title="gettext.dngettext"><code class="xref py py-func docutils literal"><span class="pre">dngettext()</span></code></a>,但如果未使用<a class="reference internal" href="#gettext.bind_textdomain_codeset" title="gettext.bind_textdomain_codeset"><code class="xref py py-func docutils literal"><span class="pre">bind_textdomain_codeset()</span></code></a>显式设置其他编码,则会在首选系统编码中返回翻译。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-55">注意,GNU <strong class="program">gettext</strong>也定义了一个<code class="xref py py-func docutils literal"><span class="pre">dcgettext()</span></code>方法,但这被认为没有用,因此目前未实现。</span></p><p><span class="yiyi-st" id="yiyi-56">以下是此API的典型用法示例:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">gettext</span><span class="o">.</span><span class="n">bindtextdomain</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">,</span> <span class="s1">'/path/to/my/language/directory'</span><span class="p">)</span>
|
||
<span class="n">gettext</span><span class="o">.</span><span class="n">textdomain</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">)</span>
|
||
<span class="n">_</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">gettext</span>
|
||
<span class="c1"># ...</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s1">'This is a translatable string.'</span><span class="p">))</span>
|
||
</code></pre></div><div class="section" id="class-based-api"><h2><span class="yiyi-st" id="yiyi-57">23.1.2. </span><span class="yiyi-st" id="yiyi-58">基于类的API </span></h2><p><span class="yiyi-st" id="yiyi-59"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块的基于类的API为您提供比GNU <strong class="program">gettext</strong> API更大的灵活性和更大的方便性。</span><span class="yiyi-st" id="yiyi-60">它是本地化您的Python应用程序和模块的推荐方式。</span><span class="yiyi-st" id="yiyi-61"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>定义了一个“translations”类,它实现了GNU <code class="file docutils literal"><span class="pre">.mo</span></code>格式文件的解析,并且有返回字符串的方法。</span><span class="yiyi-st" id="yiyi-62">此“翻译”类的实例也可以将其自身安装在内建命名空间中作为函数<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>。</span></p><dl class="function"><dt id="gettext.find"><span class="yiyi-st" id="yiyi-63"> <code class="descclassname">gettext.</code><code class="descname">find</code><span class="sig-paren">(</span><em>domain</em>, <em>localedir=None</em>, <em>languages=None</em>, <em>all=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-64">此函数实现标准的<code class="file docutils literal"><span class="pre">.mo</span></code>文件搜索算法。</span><span class="yiyi-st" id="yiyi-65">它需要一个<em>域</em>,与<a class="reference internal" href="#gettext.textdomain" title="gettext.textdomain"><code class="xref py py-func docutils literal"><span class="pre">textdomain()</span></code></a>相同。</span><span class="yiyi-st" id="yiyi-66">可选<em>localedir</em>如<a class="reference internal" href="#gettext.bindtextdomain" title="gettext.bindtextdomain"><code class="xref py py-func docutils literal"><span class="pre">bindtextdomain()</span></code></a>可选<em>languages</em>是字符串列表,其中每个字符串都是语言代码。</span></p><p><span class="yiyi-st" id="yiyi-67">如果未指定<em>localedir</em>,则使用缺省系统区域设置目录。</span><span class="yiyi-st" id="yiyi-68"><a class="footnote-reference" href="#id4" id="id2">[2] t>如果未指定<em>语言</em>,则会搜索以下环境变量:<span class="target" id="index-4"></span> <code class="xref std std-envvar docutils literal"><span class="pre">LANGUAGE</span></code>,<span class="target" id="index-5"></span> <code class="xref std std-envvar docutils literal"><span class="pre">LC_ALL</span></code>,<span class="target" id="index-6"></span> <code class="xref std std-envvar docutils literal"><span class="pre">LC_MESSAGES</span></code>和<span class="target" id="index-7"></span> <code class="xref std std-envvar docutils literal"><span class="pre">LANG</span></code>。</a></span><span class="yiyi-st" id="yiyi-69">第一个返回非空值的变量用于<em>语言</em>变量。</span><span class="yiyi-st" id="yiyi-70">环境变量应该包含一个冒号分隔的语言列表,它将在冒号上分割,以产生预期的语言代码字符串列表。</span></p><p><span class="yiyi-st" id="yiyi-71"><a class="reference internal" href="#gettext.find" title="gettext.find"><code class="xref py py-func docutils literal"><span class="pre">find()</span></code></a>然后展开并规范化语言,然后遍历它们,搜索由这些组件构成的现有文件:</span></p><p><span class="yiyi-st" id="yiyi-72"><code class="file docutils literal"><em><span class="pre">localedir</span></em> <span class="pre">/</span> <em><span class="pre">language</span></em> <span class="pre">/ LC_MESSAGES /</span> <em><span class="pre">domain</span></em> <span class="pre">.mo </span></code></span></p><p><span class="yiyi-st" id="yiyi-73">存在的第一个此类文件名由<a class="reference internal" href="#gettext.find" title="gettext.find"><code class="xref py py-func docutils literal"><span class="pre">find()</span></code></a>返回。</span><span class="yiyi-st" id="yiyi-74">如果没有找到这样的文件,则返回<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-75">如果给定<em>all</em>,则按照它们在语言列表或环境变量中出现的顺序返回所有文件名的列表。</span></p></dd></dl><dl class="function"><dt id="gettext.translation"><span class="yiyi-st" id="yiyi-76"> <code class="descclassname">gettext.</code><code class="descname">translation</code><span class="sig-paren">(</span><em>domain</em>, <em>localedir=None</em>, <em>languages=None</em>, <em>class_=None</em>, <em>fallback=False</em>, <em>codeset=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-77">返回基于<em>域</em>,<em>localedir</em>和<em>语言</em>的<code class="xref py py-class docutils literal"><span class="pre">Translations</span></code>实例,这些实例首先传递给<a class="reference internal" href="#gettext.find" title="gettext.find"><code class="xref py py-func docutils literal"><span class="pre">find()</span></code></a>获取关联的<code class="file docutils literal"><span class="pre">.mo</span></code>文件路径的列表。</span><span class="yiyi-st" id="yiyi-78">具有相同<code class="file docutils literal"><span class="pre">.mo</span></code>文件名的实例将被缓存。</span><span class="yiyi-st" id="yiyi-79">实际类实例是<em>class _</em>(如果提供),否则<code class="xref py py-class docutils literal"><span class="pre">GNUTranslations</span></code>。</span><span class="yiyi-st" id="yiyi-80">类的构造函数必须采用单个<a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">file object</span></a>参数。</span><span class="yiyi-st" id="yiyi-81">如果提供,<em>codeset</em>将更改用于在<a class="reference internal" href="#gettext.lgettext" title="gettext.lgettext"><code class="xref py py-meth docutils literal"><span class="pre">lgettext()</span></code></a>和<a class="reference internal" href="#gettext.lngettext" title="gettext.lngettext"><code class="xref py py-meth docutils literal"><span class="pre">lngettext()</span></code></a>方法中对翻译后的字符串进行编码的字符集。</span></p><p><span class="yiyi-st" id="yiyi-82">如果找到多个文件,则稍后的文件将用作早期文件的回退。</span><span class="yiyi-st" id="yiyi-83">要允许设置回退,<a class="reference internal" href="copy.html#copy.copy" title="copy.copy"><code class="xref py py-func docutils literal"><span class="pre">copy.copy()</span></code></a>用于从缓存中克隆每个翻译对象;实际的实例数据仍然与高速缓存共享。</span></p><p><span class="yiyi-st" id="yiyi-84">如果找不到<code class="file docutils literal"><span class="pre">.mo</span></code>文件,则此函数引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>;如果<em>fallback</em>为false(这是默认值),并返回<a class="reference internal" href="#gettext.NullTranslations" title="gettext.NullTranslations"><code class="xref py py-class docutils literal"><span class="pre">NullTranslations</span></code></a>实例if <em>fallback</em>为true。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-85"><span class="versionmodified">在版本3.3中更改:</span> <a class="reference internal" href="exceptions.html#IOError" title="IOError"><code class="xref py py-exc docutils literal"><span class="pre">IOError</span></code></a>已升级,而不是<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span></p></div></dd></dl><dl class="function"><dt id="gettext.install"><span class="yiyi-st" id="yiyi-86"> <code class="descclassname">gettext.</code><code class="descname">install</code><span class="sig-paren">(</span><em>domain</em>, <em>localedir=None</em>, <em>codeset=None</em>, <em>names=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-87">This installs the function <code class="xref py py-func docutils literal"><span class="pre">_()</span></code> in Python’s builtins namespace, based on <em>domain</em>, <em>localedir</em>, and <em>codeset</em> which are passed to the function <a class="reference internal" href="#gettext.translation" title="gettext.translation"><code class="xref py py-func docutils literal"><span class="pre">translation()</span></code></a>.</span></p><p><span class="yiyi-st" id="yiyi-88">对于<em>名称</em>参数,请参阅翻译对象的<a class="reference internal" href="#gettext.NullTranslations.install" title="gettext.NullTranslations.install"><code class="xref py py-meth docutils literal"><span class="pre">install()</span></code></a>方法的描述。</span></p><p><span class="yiyi-st" id="yiyi-89">如下所示,通常在应用程序中标记作为翻译候选字符串的字符串,方法是将它们包含在对<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>函数的调用中,如下所示:</span></p><pre><code class="language-python"><span></span><span class="nb">print</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s1">'This string will be translated.'</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-90">为了方便起见,您希望将<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>函数安装在Python的内置命名空间中,因此可以在应用程序的所有模块中轻松访问。</span></p></dd></dl><div class="section" id="the-nulltranslations-class"><h3><span class="yiyi-st" id="yiyi-91">23.1.2.1. </span><span class="yiyi-st" id="yiyi-92"><a class="reference internal" href="#gettext.NullTranslations" title="gettext.NullTranslations"><code class="xref py py-class docutils literal"><span class="pre">NullTranslations</span></code></a>类</span></h3><p><span class="yiyi-st" id="yiyi-93">翻译类是实际实现原始源文件消息字符串到翻译的消息字符串的翻译。</span><span class="yiyi-st" id="yiyi-94">所有翻译类使用的基类是<a class="reference internal" href="#gettext.NullTranslations" title="gettext.NullTranslations"><code class="xref py py-class docutils literal"><span class="pre">NullTranslations</span></code></a>;这提供了你可以用来编写自己的专门翻译类的基本接口。</span><span class="yiyi-st" id="yiyi-95">以下是<a class="reference internal" href="#gettext.NullTranslations" title="gettext.NullTranslations"><code class="xref py py-class docutils literal"><span class="pre">NullTranslations</span></code></a>的方法:</span></p><dl class="class"><dt id="gettext.NullTranslations"><span class="yiyi-st" id="yiyi-96"> <em class="property">class </em><code class="descclassname">gettext.</code><code class="descname">NullTranslations</code><span class="sig-paren">(</span><em>fp=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-97">使用可选的<a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">file object</span></a> <em>fp</em>,这被基类忽略。</span><span class="yiyi-st" id="yiyi-98">Initializes “protected” instance variables <em>_info</em> and <em>_charset</em> which are set by derived classes, as well as <em>_fallback</em>, which is set through <a class="reference internal" href="#gettext.NullTranslations.add_fallback" title="gettext.NullTranslations.add_fallback"><code class="xref py py-meth docutils literal"><span class="pre">add_fallback()</span></code></a>. </span><span class="yiyi-st" id="yiyi-99">然后,如果<em>fp</em>不是<code class="docutils literal"><span class="pre">None</span></code>,则调用<code class="docutils literal"><span class="pre">self._parse(fp)</span></code>。</span></p><dl class="method"><dt id="gettext.NullTranslations._parse"><span class="yiyi-st" id="yiyi-100"> <code class="descname">_parse</code><span class="sig-paren">(</span><em>fp</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-101">在基类中无操作,此方法接受文件对象<em>fp</em>,并从文件读取数据,初始化其消息目录。</span><span class="yiyi-st" id="yiyi-102">如果您具有不受支持的消息目录文件格式,则应覆盖此方法以解析您的格式。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.add_fallback"><span class="yiyi-st" id="yiyi-103"> <code class="descname">add_fallback</code><span class="sig-paren">(</span><em>fallback</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-104">添加<em>fallback</em>作为当前翻译对象的后备对象。</span><span class="yiyi-st" id="yiyi-105">如果翻译对象不能为给定的消息提供翻译,则应参考回退。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.gettext"><span class="yiyi-st" id="yiyi-106"> <code class="descname">gettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-107">如果已设置回退,则将<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-meth docutils literal"><span class="pre">gettext()</span></code></a>转发到回退。</span><span class="yiyi-st" id="yiyi-108">否则,返回已翻译的消息。</span><span class="yiyi-st" id="yiyi-109">在派生类中重写。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.lgettext"><span class="yiyi-st" id="yiyi-110"> <code class="descname">lgettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-111">如果已设置回退,则将<a class="reference internal" href="#gettext.lgettext" title="gettext.lgettext"><code class="xref py py-meth docutils literal"><span class="pre">lgettext()</span></code></a>转发到回退。</span><span class="yiyi-st" id="yiyi-112">否则,返回已翻译的消息。</span><span class="yiyi-st" id="yiyi-113">在派生类中重写。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.ngettext"><span class="yiyi-st" id="yiyi-114"> <code class="descname">ngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-115">如果已设置回退,则将<a class="reference internal" href="#gettext.ngettext" title="gettext.ngettext"><code class="xref py py-meth docutils literal"><span class="pre">ngettext()</span></code></a>转发到回退。</span><span class="yiyi-st" id="yiyi-116">否则,返回已翻译的消息。</span><span class="yiyi-st" id="yiyi-117">在派生类中重写。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.lngettext"><span class="yiyi-st" id="yiyi-118"> <code class="descname">lngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-119">如果已设置回退,则将<a class="reference internal" href="#gettext.lngettext" title="gettext.lngettext"><code class="xref py py-meth docutils literal"><span class="pre">lngettext()</span></code></a>转发到回退。</span><span class="yiyi-st" id="yiyi-120">否则,返回已翻译的消息。</span><span class="yiyi-st" id="yiyi-121">在派生类中重写。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.info"><span class="yiyi-st" id="yiyi-122"> <code class="descname">info</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-123">返回“protected”<code class="xref py py-attr docutils literal"><span class="pre">_info</span></code>变量。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.charset"><span class="yiyi-st" id="yiyi-124"> <code class="descname">charset</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-125">返回“protected”<code class="xref py py-attr docutils literal"><span class="pre">_charset</span></code>变量,它是消息目录文件的编码。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.output_charset"><span class="yiyi-st" id="yiyi-126"> <code class="descname">output_charset</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-127">返回“protected”<code class="xref py py-attr docutils literal"><span class="pre">_output_charset</span></code>变量,它定义用于在<a class="reference internal" href="#gettext.lgettext" title="gettext.lgettext"><code class="xref py py-meth docutils literal"><span class="pre">lgettext()</span></code></a>和<a class="reference internal" href="#gettext.lngettext" title="gettext.lngettext"><code class="xref py py-meth docutils literal"><span class="pre">lngettext()</span></code></a>中返回已翻译消息的编码。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.set_output_charset"><span class="yiyi-st" id="yiyi-128"> <code class="descname">set_output_charset</code><span class="sig-paren">(</span><em>charset</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-129">更改“protected”<code class="xref py py-attr docutils literal"><span class="pre">_output_charset</span></code>变量,该变量定义用于返回已翻译消息的编码。</span></p></dd></dl><dl class="method"><dt id="gettext.NullTranslations.install"><span class="yiyi-st" id="yiyi-130"> <code class="descname">install</code><span class="sig-paren">(</span><em>names=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-131">此方法将<code class="xref py py-meth docutils literal"><span class="pre">self.gettext()</span></code>安装到内建命名空间中,将其绑定到<code class="docutils literal"><span class="pre">_</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-132">如果给出了<em>names</em>参数,它必须是包含除了<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>之外的要在builtins命名空间中安装的函数的名称的序列。</span><span class="yiyi-st" id="yiyi-133">支持的名称是<code class="docutils literal"><span class="pre">'gettext'</span></code>(绑定到<code class="xref py py-meth docutils literal"><span class="pre">self.gettext()</span></code>),<code class="docutils literal"><span class="pre">'ngettext'</span></code>(绑定到<code class="xref py py-meth docutils literal"><span class="pre">self.ngettext()</span></code>),<code class="docutils literal"><span class="pre">'lgettext'</span></code>和<code class="docutils literal"><span class="pre">'lngettext'</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-134">注意,这只是一种方法,尽管是最方便的方法,使<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>函数可用于您的应用程序。</span><span class="yiyi-st" id="yiyi-135">因为它影响整个应用程序,特别是内建命名空间,本地化模块不应安装<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>。</span><span class="yiyi-st" id="yiyi-136">相反,他们应该使用此代码使<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>可用于他们的模块:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">t</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">translation</span><span class="p">(</span><span class="s1">'mymodule'</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
|
||
<span class="n">_</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">gettext</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-137">这会将<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>仅放置在模块的全局命名空间中,因此仅影响此模块中的调用。</span></p></dd></dl></dd></dl></div><div class="section" id="the-gnutranslations-class"><h3><span class="yiyi-st" id="yiyi-138">23.1.2.2. </span><span class="yiyi-st" id="yiyi-139"><code class="xref py py-class docutils literal"><span class="pre">GNUTranslations</span></code>类</span></h3><p><span class="yiyi-st" id="yiyi-140"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块提供了从<a class="reference internal" href="#gettext.NullTranslations" title="gettext.NullTranslations"><code class="xref py py-class docutils literal"><span class="pre">NullTranslations</span></code></a>:<code class="xref py py-class docutils literal"><span class="pre">GNUTranslations</span></code>派生的一个附加类。</span><span class="yiyi-st" id="yiyi-141">此类覆盖<code class="xref py py-meth docutils literal"><span class="pre">_parse()</span></code>以启用以big-endian和little-endian格式读取GNU <strong class="program">gettext</strong>格式<code class="file docutils literal"><span class="pre">.mo</span></code>文件。</span></p><p><span class="yiyi-st" id="yiyi-142"><code class="xref py py-class docutils literal"><span class="pre">GNUTranslations</span></code>解析翻译目录中的可选元数据。</span><span class="yiyi-st" id="yiyi-143">使用GNU <strong class="program">gettext</strong>来包含元数据作为空字符串的转换是惯例。</span><span class="yiyi-st" id="yiyi-144">此元数据位于<span class="target" id="index-8"></span> <a class="rfc reference external" href="https://tools.ietf.org/html/rfc822.html"><strong>RFC 822</strong></a> - 样式<code class="docutils literal"><span class="pre">键:</span> <span class="pre">值</span> 并应包含<code class="docutils literal"><span class="pre">Project-Id-Version</span></code>键。</code></span><span class="yiyi-st" id="yiyi-145">如果找到键<code class="docutils literal"><span class="pre">Content-Type</span></code>,则<code class="docutils literal"><span class="pre">charset</span></code>属性用于初始化“protected”<code class="xref py py-attr docutils literal"><span class="pre">_charset</span></code>实例变量,默认为<code class="docutils literal"><span class="pre">None</span></code>(如果找不到)。</span><span class="yiyi-st" id="yiyi-146">如果指定了字符集编码,则从目录读取的所有消息标识和消息字符串都将使用此编码转换为Unicode,否则假定为ASCII编码。</span></p><p><span class="yiyi-st" id="yiyi-147">由于消息id也被读为Unicode字符串,所有<code class="xref py py-meth docutils literal"><span class="pre">*gettext()</span></code>方法将假设消息id为Unicode字符串,而不是字节字符串。</span></p><p><span class="yiyi-st" id="yiyi-148">整个键/值对集合被放置到字典中并设置为“protected”<code class="xref py py-attr docutils literal"><span class="pre">_info</span></code>实例变量。</span></p><p><span class="yiyi-st" id="yiyi-149">如果<code class="file docutils literal"><span class="pre">.mo</span></code>文件的幻数无效,主版本号是意外的,或者如果在读取文件时出现其他问题,则实例化<code class="xref py py-class docutils literal"><span class="pre">GNUTranslations</span></code>类可以引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-150">从基类实现覆盖以下方法:</span></p><dl class="method"><dt id="gettext.GNUTranslations.gettext"><span class="yiyi-st" id="yiyi-151"> <code class="descclassname">GNUTranslations.</code><code class="descname">gettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-152">在目录中查找<em>消息</em> id,并返回相应的消息字符串作为Unicode字符串。</span><span class="yiyi-st" id="yiyi-153">如果目录中没有针对<em>消息</em> id的条目,并且设置了回退,则将查找转发到回退的<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-meth docutils literal"><span class="pre">gettext()</span></code></a>方法。</span><span class="yiyi-st" id="yiyi-154">否则,返回<em>消息</em> id。</span></p></dd></dl><dl class="method"><dt id="gettext.GNUTranslations.lgettext"><span class="yiyi-st" id="yiyi-155"> <code class="descclassname">GNUTranslations.</code><code class="descname">lgettext</code><span class="sig-paren">(</span><em>message</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-156">等效于<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-meth docutils literal"><span class="pre">gettext()</span></code></a>,但是如果未使用<code class="xref py py-meth docutils literal"><span class="pre">set_output_charset()</span></code></span></p></dd></dl><dl class="method"><dt id="gettext.GNUTranslations.ngettext"><span class="yiyi-st" id="yiyi-157"> <code class="descclassname">GNUTranslations.</code><code class="descname">ngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-158">执行消息id的复数形式查找。</span><span class="yiyi-st" id="yiyi-159"><em>奇异</em>用作消息id以用于在目录中查找,而<em>n</em>用于确定使用哪个复数形式。</span><span class="yiyi-st" id="yiyi-160">返回的消息字符串是Unicode字符串。</span></p><p><span class="yiyi-st" id="yiyi-161">如果在目录中找不到消息标识,并且指定了回退,则会将请求转发到回退的<a class="reference internal" href="#gettext.ngettext" title="gettext.ngettext"><code class="xref py py-meth docutils literal"><span class="pre">ngettext()</span></code></a>方法。</span><span class="yiyi-st" id="yiyi-162">否则,当<em>n</em>为1 <em>时返回奇异</em>,在所有其他情况下返回<em>多个</em>。</span></p><p><span class="yiyi-st" id="yiyi-163">这里是一个例子:</span></p><pre><code class="language-python"><span></span><span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="s1">'.'</span><span class="p">))</span>
|
||
<span class="n">cat</span> <span class="o">=</span> <span class="n">GNUTranslations</span><span class="p">(</span><span class="n">somefile</span><span class="p">)</span>
|
||
<span class="n">message</span> <span class="o">=</span> <span class="n">cat</span><span class="o">.</span><span class="n">ngettext</span><span class="p">(</span>
|
||
<span class="s1">'There is </span><span class="si">%(num)d</span><span class="s1"> file in this directory'</span><span class="p">,</span>
|
||
<span class="s1">'There are </span><span class="si">%(num)d</span><span class="s1"> files in this directory'</span><span class="p">,</span>
|
||
<span class="n">n</span><span class="p">)</span> <span class="o">%</span> <span class="p">{</span><span class="s1">'num'</span><span class="p">:</span> <span class="n">n</span><span class="p">}</span>
|
||
</code></pre></dd></dl><dl class="method"><dt id="gettext.GNUTranslations.lngettext"><span class="yiyi-st" id="yiyi-164"> <code class="descclassname">GNUTranslations.</code><code class="descname">lngettext</code><span class="sig-paren">(</span><em>singular</em>, <em>plural</em>, <em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-165">等效于<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-meth docutils literal"><span class="pre">gettext()</span></code></a>,但是如果未使用<code class="xref py py-meth docutils literal"><span class="pre">set_output_charset()</span></code></span></p></dd></dl></div><div class="section" id="solaris-message-catalog-support"><h3><span class="yiyi-st" id="yiyi-166">23.1.2.3. </span><span class="yiyi-st" id="yiyi-167">Solaris消息目录支持</span></h3><p><span class="yiyi-st" id="yiyi-168">Solaris操作系统定义了自己的二进制<code class="file docutils literal"><span class="pre">.mo</span></code>文件格式,但由于在此格式中找不到任何文档,因此目前不支持此格式。</span></p></div><div class="section" id="the-catalog-constructor"><h3><span class="yiyi-st" id="yiyi-169">23.1.2.4. </span><span class="yiyi-st" id="yiyi-170">目录构造函数</span></h3><p id="index-9"><span class="yiyi-st" id="yiyi-171">GNOME使用James Henstridge的<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块的版本,但是这个版本有一个稍微不同的API。</span><span class="yiyi-st" id="yiyi-172">其记录的用法是:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">cat</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">Catalog</span><span class="p">(</span><span class="n">domain</span><span class="p">,</span> <span class="n">localedir</span><span class="p">)</span>
|
||
<span class="n">_</span> <span class="o">=</span> <span class="n">cat</span><span class="o">.</span><span class="n">gettext</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s1">'hello world'</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-173">为了与此旧模块兼容,函数<code class="xref py py-func docutils literal"><span class="pre">Catalog()</span></code>是上述<a class="reference internal" href="#gettext.translation" title="gettext.translation"><code class="xref py py-func docutils literal"><span class="pre">translation()</span></code></a>函数的别名。</span></p><p><span class="yiyi-st" id="yiyi-174">这个模块和Henstridge之间的一个区别:他的目录对象支持通过映射API访问,但是这似乎没有使用,因此目前不支持。</span></p></div></div><div class="section" id="internationalizing-your-programs-and-modules"><h2><span class="yiyi-st" id="yiyi-175">23.1.3. </span><span class="yiyi-st" id="yiyi-176">国际化您的程序和模块</span></h2><p><span class="yiyi-st" id="yiyi-177">国际化(I18N)指的是使程序知道多种语言的操作。</span><span class="yiyi-st" id="yiyi-178">本地化(L10N)是指一旦国际化,您的程序适应当地语言和文化习惯。</span><span class="yiyi-st" id="yiyi-179">为了为您的Python程序提供多语言消息,您需要执行以下步骤:</span></p><ol class="arabic simple"><li><span class="yiyi-st" id="yiyi-180">通过专门标记可翻译字符串来准备您的程序或模块</span></li><li><span class="yiyi-st" id="yiyi-181">在标记的文件上运行一套工具来生成原始消息目录</span></li><li><span class="yiyi-st" id="yiyi-182">创建消息目录的语言特定翻译</span></li><li><span class="yiyi-st" id="yiyi-183">请使用<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块,以便正确翻译消息字符串</span></li></ol><p><span class="yiyi-st" id="yiyi-184">为了准备I18N的代码,您需要查看文件中的所有字符串。</span><span class="yiyi-st" id="yiyi-185">任何需要翻译的字符串都应该用<code class="docutils literal"><span class="pre">_('...')</span></code>进行标记 - 也就是调用<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>。</span><span class="yiyi-st" id="yiyi-186">例如:</span></p><pre><code class="language-python"><span></span><span class="n">filename</span> <span class="o">=</span> <span class="s1">'mylog.txt'</span>
|
||
<span class="n">message</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s1">'writing a log message'</span><span class="p">)</span>
|
||
<span class="n">fp</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
|
||
<span class="n">fp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
|
||
<span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-187">在此示例中,字符串<code class="docutils literal"><span class="pre">'写入</span> <span class="pre">a</span> <span class="pre">日志</span> <span class="pre">消息'</span> ,而字符串<code class="docutils literal"><span class="pre">'mylog.txt'</span></code>和<code class="docutils literal"><span class="pre">'w'</span></code>则不是。</code></span></p><p><span class="yiyi-st" id="yiyi-188">有一些工具来提取要翻译的字符串。</span><span class="yiyi-st" id="yiyi-189">原始的GNU <strong class="program">gettext</strong>仅支持C或C ++源代码,但其扩展版本<strong class="program">xgettext</strong>扫描以多种语言(包括Python)编写的代码,以查找标记为可翻译的字符串。</span><span class="yiyi-st" id="yiyi-190"><a class="reference external" href="http://babel.pocoo.org/">Babel</a>是一个Python国际化库,其中包含用于提取和编译消息目录的<code class="file docutils literal"><span class="pre">pybabel</span></code>脚本。</span><span class="yiyi-st" id="yiyi-191">FrançoisPinard的名为<strong class="program">xpot</strong>的程序执行类似的工作,并且作为他的<a class="reference external" href="https://github.com/pinard/po-utils">po-utils包的一部分</a>提供。</span></p><p><span class="yiyi-st" id="yiyi-192">(Python还包括这些程序的纯Python版本,称为<strong class="program">pygettext.py</strong>和<strong class="program">msgfmt.py</strong>;一些Python发行版将为您安装它们。</span><span class="yiyi-st" id="yiyi-193"><strong class="program">pygettext.py</strong>类似于<strong class="program">xgettext</strong>,但只能理解Python源代码,不能处理其他编程语言,如C或C ++。</span><span class="yiyi-st" id="yiyi-194"><strong class="program">pygettext.py</strong>支持类似于<strong class="program">xgettext</strong>的命令行界面;有关其使用的详细信息,请运行<code class="docutils literal"><span class="pre">pygettext.py</span> <span class="pre">--help</span></code>。</span><span class="yiyi-st" id="yiyi-195"><strong class="program">msgfmt.py</strong>与GNU <strong class="program">msgfmt</strong>是二进制兼容的。</span><span class="yiyi-st" id="yiyi-196">使用这两个程序,您可能不需要GNU <strong class="program">gettext</strong>包来将您的Python应用程序国际化。)</span></p><p><span class="yiyi-st" id="yiyi-197"><strong class="program">xgettext</strong>,<strong class="program">pygettext</strong>和类似工具生成的消息目录<code class="file docutils literal"><span class="pre">.po</span></code>文件。</span><span class="yiyi-st" id="yiyi-198">它们是结构化的人类可读文件,包含源代码中的每个标记字符串,以及这些字符串的翻译版本的占位符。</span></p><p><span class="yiyi-st" id="yiyi-199">然后将这些<code class="file docutils literal"><span class="pre">.po</span></code>文件的副本移交给为每种支持的自然语言编写翻译的个人翻译员。</span><span class="yiyi-st" id="yiyi-200">他们将完整的语言特定版本作为<code class="file docutils literal"><span class="pre"><language-name>.po</span></code>文件发回,该文件被编译为机器可读的<code class="file docutils literal"><span class="pre">.mo</span></code>二进制目录文件,使用<strong class="program"> msgfmt</strong>程序。</span><span class="yiyi-st" id="yiyi-201"><code class="file docutils literal"><span class="pre">.mo</span></code>文件由<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块用于运行时的实际转换处理。</span></p><p><span class="yiyi-st" id="yiyi-202">如何在代码中使用<a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块取决于您是否将单个模块或整个应用程序国际化。</span><span class="yiyi-st" id="yiyi-203">接下来的两节将讨论每个案例。</span></p><div class="section" id="localizing-your-module"><h3><span class="yiyi-st" id="yiyi-204">23.1.3.1. </span><span class="yiyi-st" id="yiyi-205">Localizing your module</span></h3><p><span class="yiyi-st" id="yiyi-206">如果您要本地化您的模块,则必须注意不要进行全局更改,例如</span><span class="yiyi-st" id="yiyi-207">到内建命名空间。</span><span class="yiyi-st" id="yiyi-208">您不应使用GNU <code class="docutils literal"><span class="pre">gettext</span></code> API,而应使用基于类的API。</span></p><p><span class="yiyi-st" id="yiyi-209">假设您的模块称为“垃圾邮件”,并且该模块的各种自然语言翻译<code class="file docutils literal"><span class="pre">.mo</span></code>文件位于GNU <strong class="program">gettext</strong>中的<code class="file docutils literal"><span class="pre">/usr/share/locale</span></code> >格式。</span><span class="yiyi-st" id="yiyi-210">这里是你将放在模块的顶部:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">t</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">translation</span><span class="p">(</span><span class="s1">'spam'</span><span class="p">,</span> <span class="s1">'/usr/share/locale'</span><span class="p">)</span>
|
||
<span class="n">_</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">lgettext</span>
|
||
</code></pre></div><div class="section" id="localizing-your-application"><h3><span class="yiyi-st" id="yiyi-211">23.1.3.2. </span><span class="yiyi-st" id="yiyi-212">本地化您的应用程序</span></h3><p><span class="yiyi-st" id="yiyi-213">如果要本地化应用程序,可以将<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>函数全局安装到内建命名空间中,通常位于应用程序的主驱动程序文件中。</span><span class="yiyi-st" id="yiyi-214">这将使所有特定于应用程序的文件只使用<code class="docutils literal"><span class="pre">_('...')</span></code>,而无需在每个文件中显式安装。</span></p><p><span class="yiyi-st" id="yiyi-215">在简单的情况下,您只需要将以下位代码添加到应用程序的主驱动程序文件中:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">gettext</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-216">如果需要设置locale目录,可以将其传递到<a class="reference internal" href="#gettext.install" title="gettext.install"><code class="xref py py-func docutils literal"><span class="pre">install()</span></code></a>函数中:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
<span class="n">gettext</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">,</span> <span class="s1">'/usr/share/locale'</span><span class="p">)</span>
|
||
</code></pre></div><div class="section" id="changing-languages-on-the-fly"><h3><span class="yiyi-st" id="yiyi-217">23.1.3.3. </span><span class="yiyi-st" id="yiyi-218">随时更改语言</span></h3><p><span class="yiyi-st" id="yiyi-219">如果您的程序需要同时支持多种语言,您可能需要创建多个翻译实例,然后明确地在它们之间切换,如下所示:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">gettext</span>
|
||
|
||
<span class="n">lang1</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">translation</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">,</span> <span class="n">languages</span><span class="o">=</span><span class="p">[</span><span class="s1">'en'</span><span class="p">])</span>
|
||
<span class="n">lang2</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">translation</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">,</span> <span class="n">languages</span><span class="o">=</span><span class="p">[</span><span class="s1">'fr'</span><span class="p">])</span>
|
||
<span class="n">lang3</span> <span class="o">=</span> <span class="n">gettext</span><span class="o">.</span><span class="n">translation</span><span class="p">(</span><span class="s1">'myapplication'</span><span class="p">,</span> <span class="n">languages</span><span class="o">=</span><span class="p">[</span><span class="s1">'de'</span><span class="p">])</span>
|
||
|
||
<span class="c1"># start by using language1</span>
|
||
<span class="n">lang1</span><span class="o">.</span><span class="n">install</span><span class="p">()</span>
|
||
|
||
<span class="c1"># ... time goes by, user selects language 2</span>
|
||
<span class="n">lang2</span><span class="o">.</span><span class="n">install</span><span class="p">()</span>
|
||
|
||
<span class="c1"># ... more time goes by, user selects language 3</span>
|
||
<span class="n">lang3</span><span class="o">.</span><span class="n">install</span><span class="p">()</span>
|
||
</code></pre></div><div class="section" id="deferred-translations"><h3><span class="yiyi-st" id="yiyi-220">23.1.3.4. </span><span class="yiyi-st" id="yiyi-221">延期翻译</span></h3><p><span class="yiyi-st" id="yiyi-222">在大多数编码情况下,字符串在它们被编码的地方被转换。</span><span class="yiyi-st" id="yiyi-223">然而,偶尔,您需要标记字符串进行翻译,但推迟实际翻译直到稍后。</span><span class="yiyi-st" id="yiyi-224">一个典型的例子是:</span></p><pre><code class="language-python"><span></span><span class="n">animals</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'mollusk'</span><span class="p">,</span>
|
||
<span class="s1">'albatross'</span><span class="p">,</span>
|
||
<span class="s1">'rat'</span><span class="p">,</span>
|
||
<span class="s1">'penguin'</span><span class="p">,</span>
|
||
<span class="s1">'python'</span><span class="p">,</span> <span class="p">]</span>
|
||
<span class="c1"># ...</span>
|
||
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">animals</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-225">在这里,您要将<code class="docutils literal"><span class="pre">animals</span></code>列表中的字符串标记为可翻译,但实际上您不想翻译它们,直到它们打印。</span></p><p><span class="yiyi-st" id="yiyi-226">这里有一种方法可以处理这种情况:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">_</span><span class="p">(</span><span class="n">message</span><span class="p">):</span> <span class="k">return</span> <span class="n">message</span>
|
||
|
||
<span class="n">animals</span> <span class="o">=</span> <span class="p">[</span><span class="n">_</span><span class="p">(</span><span class="s1">'mollusk'</span><span class="p">),</span>
|
||
<span class="n">_</span><span class="p">(</span><span class="s1">'albatross'</span><span class="p">),</span>
|
||
<span class="n">_</span><span class="p">(</span><span class="s1">'rat'</span><span class="p">),</span>
|
||
<span class="n">_</span><span class="p">(</span><span class="s1">'penguin'</span><span class="p">),</span>
|
||
<span class="n">_</span><span class="p">(</span><span class="s1">'python'</span><span class="p">),</span> <span class="p">]</span>
|
||
|
||
<span class="k">del</span> <span class="n">_</span>
|
||
|
||
<span class="c1"># ...</span>
|
||
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">animals</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-227">这是因为<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>的虚拟定义简单地返回不变的字符串。</span><span class="yiyi-st" id="yiyi-228">这个虚拟定义将临时覆盖内建命名空间中的<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>的任何定义(直到<a class="reference internal" href="../reference/simple_stmts.html#del"><code class="xref std std-keyword docutils literal"><span class="pre">del</span></code></a>命令)。</span><span class="yiyi-st" id="yiyi-229">注意,虽然如果你在本地命名空间中有之前的定义<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-230">注意,<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>的第二次使用不会将“a”标识为可翻译为<strong class="program">gettext</strong>程序,因为该参数不是字符串字面值。</span></p><p><span class="yiyi-st" id="yiyi-231">另一种处理这种情况的方法是使用以下示例:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">N_</span><span class="p">(</span><span class="n">message</span><span class="p">):</span> <span class="k">return</span> <span class="n">message</span>
|
||
|
||
<span class="n">animals</span> <span class="o">=</span> <span class="p">[</span><span class="n">N_</span><span class="p">(</span><span class="s1">'mollusk'</span><span class="p">),</span>
|
||
<span class="n">N_</span><span class="p">(</span><span class="s1">'albatross'</span><span class="p">),</span>
|
||
<span class="n">N_</span><span class="p">(</span><span class="s1">'rat'</span><span class="p">),</span>
|
||
<span class="n">N_</span><span class="p">(</span><span class="s1">'penguin'</span><span class="p">),</span>
|
||
<span class="n">N_</span><span class="p">(</span><span class="s1">'python'</span><span class="p">),</span> <span class="p">]</span>
|
||
|
||
<span class="c1"># ...</span>
|
||
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">animals</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-232">在这种情况下,您使用函数<code class="xref py py-func docutils literal"><span class="pre">N_()</span></code>标记可翻译字符串,这不会与任何定义<code class="xref py py-func docutils literal"><span class="pre">_()</span></code>冲突。</span><span class="yiyi-st" id="yiyi-233">但是,您需要教您的消息提取程序以查找标有<code class="xref py py-func docutils literal"><span class="pre">N_()</span></code>的可翻译字符串。</span><span class="yiyi-st" id="yiyi-234"><strong class="program">xgettext</strong>,<strong class="program">pygettext</strong>,<code class="docutils literal"><span class="pre">pybabel</span> <span class="pre">提取</span></code>和<strong class="program">> all通过使用<code class="xref std std-option docutils literal"><span class="pre">-k</span></code>命令行开关支持此功能。</strong></span><span class="yiyi-st" id="yiyi-235">这里的<code class="xref py py-func docutils literal"><span class="pre">N_()</span></code>的选择是完全任意的;它可以很容易地是<code class="xref py py-func docutils literal"><span class="pre">MarkThisStringForTranslation()</span></code>。</span></p></div></div><div class="section" id="acknowledgements"><h2><span class="yiyi-st" id="yiyi-236">23.1.4. </span><span class="yiyi-st" id="yiyi-237">致谢</span></h2><p><span class="yiyi-st" id="yiyi-238">以下人员提供了代码,反馈,设计建议,以前的实现,以及创建此模块的宝贵经验:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-239">彼得·福克</span></li><li><span class="yiyi-st" id="yiyi-240">詹姆斯亨斯特里奇</span></li><li><span class="yiyi-st" id="yiyi-241">Juan DavidIbáñezPalomar</span></li><li><span class="yiyi-st" id="yiyi-242">Marc-AndréLemburg</span></li><li><span class="yiyi-st" id="yiyi-243">Martin vonLöwis</span></li><li><span class="yiyi-st" id="yiyi-244">FrançoisPinard</span></li><li><span class="yiyi-st" id="yiyi-245">巴里华沙</span></li><li><span class="yiyi-st" id="yiyi-246">古斯塔沃尼迈耶</span></li></ul><p class="rubric"><span class="yiyi-st" id="yiyi-247">脚注</span></p><table class="docutils footnote" frame="void" id="id3" rules="none"><tbody valign="top"><tr><td class="label"><span class="yiyi-st" id="yiyi-248"><a class="fn-backref" href="#id1">[1]</a></span></td><td><span class="yiyi-st" id="yiyi-249">默认语言环境目录是系统相关的;例如,在RedHat Linux上,它是<code class="file docutils literal"><span class="pre">/usr/share/locale</span></code>,但在Solaris上是<code class="file docutils literal"><span class="pre">/usr/lib/locale</span></code>。</span><span class="yiyi-st" id="yiyi-250"><a class="reference internal" href="#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal"><span class="pre">gettext</span></code></a>模块不会尝试支持这些系统相关的默认值;而默认值为<code class="file docutils literal"><span class="pre">sys.prefix/share/locale</span></code>。</span><span class="yiyi-st" id="yiyi-251">因此,最好在应用程序开始时使用显式绝对路径调用<a class="reference internal" href="#gettext.bindtextdomain" title="gettext.bindtextdomain"><code class="xref py py-func docutils literal"><span class="pre">bindtextdomain()</span></code></a>。</span></td></tr></tbody></table><table class="docutils footnote" frame="void" id="id4" rules="none"><tbody valign="top"><tr><td class="label"><span class="yiyi-st" id="yiyi-252"><a class="fn-backref" href="#id2">[2]</a></span></td><td><span class="yiyi-st" id="yiyi-253">请参阅上面<a class="reference internal" href="#gettext.bindtextdomain" title="gettext.bindtextdomain"><code class="xref py py-func docutils literal"><span class="pre">bindtextdomain()</span></code></a>的脚注。</span></td></tr></tbody></table></div></div></div> |