Документация Python неофициальный перевод

gettext.md

578 строк · 41.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.0/library/gettext.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `gettext` – Многоязычные службы интернационализации89Модуль `gettext` предоставляет службы интернационализации (I18N) и локализации (L10N) для ваших модулей и приложений Python. Он поддерживает как GNU `gettext` API каталогов сообщений, так и более высокоуровневый, основанный на классах API, который может быть более подходящим для файлов Python. Описанный ниже интерфейс позволяет писать сообщения модуля и приложения на одном естественном языке и предоставлять каталог переведённых сообщений для работы на разных естественных языках.1011Также даются некоторые советы по локализации модулей и приложений Python.1213## API GNU **gettext**1415Модуль `gettext` определяет следующий API, очень похожий на GNU **gettext** API. Если вы используете этот API, он повлияет на перевод всего вашего приложения глобально. Часто это то, что нужно, если ваше приложение одноязычно, а выбор языка зависит от локали пользователя. Если вы локализуете модуль Python или ваше приложение должно переключать языки на лету, вероятно, вы захотите использовать вместо этого основанный на классах API.1617#### `[gettext.bindtextdomain]gettext.bindtextdomain(domain[, localedir])`1819Привязывает домен *domain* к каталогу локали *localedir*. Конкретнее, `gettext` будет искать двоичные файлы `.mo` для указанного домена по пути (в Unix): `localedir/language/LC_MESSAGES/domain.mo`, где *languages* ищется в переменных окружения **LANGUAGE**, **LC\_ALL**, **LC\_MESSAGES** и **LANG** соответственно.2021Если *localedir* опущен или равен `None`, возвращается текущая привязка для *domain*. [\[1\]](https://python-all.ru/3.0/library/gettext.html#id6)2223#### `[gettext.bind_textdomain_codeset]gettext.bind_textdomain_codeset(domain[, codeset])`2425Привязывает2627*domain*2829к3031*codeset*3233, изменяя кодировку строк, возвращаемых семейством функций3435[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)3637. Если3839*codeset*4041опущен, возвращается текущая привязка.4243#### `[gettext.textdomain]gettext.textdomain([domain])`4445Изменяет или запрашивает текущий глобальный domain. Если4647*domain*4849равен5051`None`5253, возвращается текущий глобальный domain; в противном случае глобальный domain устанавливается в5455*domain*5657, который и возвращается.5859#### `[gettext.gettext]gettext.gettext(message)`6061Возвращает локализованный перевод6263*message*6465на основе текущего глобального домена, языка и каталога локали. Эта функция обычно имеет псевдоним6667`_()`6869в локальном пространстве имён (см. примеры ниже).7071#### `[gettext.lgettext]gettext.lgettext(message)`7273Эквивалентно7475[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)7677, но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью7879[`bind_textdomain_codeset()`](https://python-all.ru/3.0/library/gettext.html#gettext.bind_textdomain_codeset)8081.8283#### `[gettext.dgettext]gettext.dgettext(domain, message)`8485Как и8687[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)8889, но ищет сообщение в указанном9091*domain*9293.9495#### `[gettext.ldgettext]gettext.ldgettext(domain, message)`9697Эквивалентно9899[`dgettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.dgettext)100101, но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью102103[`bind_textdomain_codeset()`](https://python-all.ru/3.0/library/gettext.html#gettext.bind_textdomain_codeset)104105.106107#### `[gettext.ngettext]gettext.ngettext(singular, plural, n)`108109Как и [`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext), но учитывает формы множественного числа. Если перевод найден, применяет формулу множественного числа к *n* и возвращает результирующее сообщение (в некоторых языках более двух форм множественного числа). Если перевод не найден, возвращает *singular*, если *n* равно 1; в противном случае возвращает *plural*.110111Формула множественного числа берётся из заголовка каталога. Это выражение на C или Python с переменной *n*; выражение вычисляет индекс множественного числа в каталоге. Обратитесь к документации GNU gettext за точным синтаксисом, используемым в файлах `.po`, а также за формулами для разных языков.112113#### `[gettext.lngettext]gettext.lngettext(singular, plural, n)`114115Эквивалентно116117[`ngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.ngettext)118119, но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью120121[`bind_textdomain_codeset()`](https://python-all.ru/3.0/library/gettext.html#gettext.bind_textdomain_codeset)122123.124125#### `[gettext.dngettext]gettext.dngettext(domain, singular, plural, n)`126127Как и128129[`ngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.ngettext)130131, но ищет сообщение в указанном132133*domain*134135.136137#### `[gettext.ldngettext]gettext.ldngettext(domain, singular, plural, n)`138139Эквивалентно140141[`dngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.dngettext)142143, но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью144145[`bind_textdomain_codeset()`](https://python-all.ru/3.0/library/gettext.html#gettext.bind_textdomain_codeset)146147.148149Обратите внимание, что GNU **gettext** также определяет метод `dcgettext()`, но он был признан не полезным и поэтому в настоящее время не реализован.150151Вот пример типичного использования этого API:152153```python154import gettext155gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')156gettext.textdomain('myapplication')157_ = gettext.gettext158# ...159print(_('This is a translatable string.'))160```161162## API на основе классов163164Основанный на классах API модуля `gettext` обеспечивает большую гибкость и удобство, чем GNU **gettext** API. Это рекомендуемый способ локализации ваших приложений и модулей Python. `gettext` определяет класс «translations», который реализует разбор файлов формата GNU `.mo` и содержит методы для возврата строк. Экземпляры этого класса «translations» также могут устанавливать себя во встроенное пространство имён как функцию `_()`.165166#### `[gettext.find]gettext.find(domain[, localedir[, languages[, all]]])`167168Эта функция реализует стандартный алгоритм поиска файлов `.mo`. Она принимает *domain*, такой же, как в [`textdomain()`](https://python-all.ru/3.0/library/gettext.html#gettext.textdomain). Необязательный *localedir* – как в [`bindtextdomain()`](https://python-all.ru/3.0/library/gettext.html#gettext.bindtextdomain). Необязательный *languages* – это список строк, где каждая строка – код языка.169170Если *localedir* не указан, используется системный каталог локали по умолчанию. [\[2\]](https://python-all.ru/3.0/library/gettext.html#id7) Если *languages* не указан, то выполняется поиск по следующим переменным окружения: **LANGUAGE**, **LC\_ALL**, **LC\_MESSAGES** и **LANG**. Первая, возвращающая непустое значение, используется для переменной *languages*. Переменные окружения должны содержать разделённый двоеточиями список языков, который будет разделён по двоеточию для получения ожидаемого списка кодов языков.171172Затем [`find()`](https://python-all.ru/3.0/library/gettext.html#gettext.find) расширяет и нормализует языки и перебирает их в поисках существующего файла, построенного из следующих компонентов:173174`localedir/language/LC_MESSAGES/domain.mo`175176Первое из таких имён файлов, которое существует, возвращается функцией [`find()`](https://python-all.ru/3.0/library/gettext.html#gettext.find). Если такого файла нет, возвращается `None`. Если указан параметр *all*, возвращается список всех имён файлов в том порядке, в котором они встречаются в списке языков или в переменных окружения.177178#### `[gettext.translation]gettext.translation(domain[, localedir[, languages[, class_[, fallback[, codeset]]]]])`179180Возвращает экземпляр `Translations`, созданный на основе *domain*, *localedir* и *languages*, которые сначала передаются в [`find()`](https://python-all.ru/3.0/library/gettext.html#gettext.find) для получения списка соответствующих путей к файлам `.mo`. Экземпляры с одинаковыми именами файлов `.mo` кэшируются. Фактически создаётся экземпляр *class\_*, если он указан, иначе `GNUTranslations`. Конструктор класса должен принимать один аргумент – файловый объект. Если указан *codeset*, он изменит кодировку, используемую для кодирования переведённых строк в методах [`lgettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.lgettext) и [`lngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.lngettext).181182Если найдено несколько файлов, более поздние используются как резервные для более ранних. Чтобы разрешить установку резервного варианта, для клонирования каждого объекта перевода из кэша используется `copy.copy()`; при этом фактические данные экземпляра по-прежнему разделяются с кэшем.183184Если файл `.mo` не найден, эта функция возбуждает [`IOError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IOError), если *fallback* имеет значение false (по умолчанию), и возвращает экземпляр [`NullTranslations`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations), если *fallback* равно true.185186#### `install(domain[, localedir[, codeset[, names]]]])`187188Эта функция устанавливает функцию `_()` во встроенное пространство имён Python на основе *domain*, *localedir* и *codeset*, которые передаются функции [`translation()`](https://python-all.ru/3.0/library/gettext.html#gettext.translation).189190Для параметра *names* обратитесь к описанию метода `install()` объекта перевода.191192Как показано ниже, строки в приложении, предназначенные для перевода, обычно помечаются обёртыванием их в вызов функции `_()`, например:193194```python195print(_('This string will be translated.'))196```197198Для удобства можно установить функцию `_()` во встроенное пространство имён Python, чтобы она была легко доступна во всех модулях вашего приложения.199200### Класс [`NullTranslations`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations)201202Классы перевода – это то, что фактически реализует перевод строк исходного сообщения в переведённые строки. Базовым классом, используемым всеми классами перевода, является [`NullTranslations`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations); он предоставляет базовый интерфейс, который можно использовать для написания собственных специализированных классов перевода. Ниже приведены методы класса [`NullTranslations`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations):203204#### `[gettext.NullTranslations]class gettext.NullTranslations([fp])`205206Принимает необязательный файловый объект *fp*, который игнорируется базовым классом. Инициализирует «защищённые» переменные экземпляра *\_info* и *\_charset*, которые устанавливаются производными классами, а также *\_fallback*, который устанавливается через [`add_fallback()`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations.add_fallback). Затем вызывает `self._parse(fp)`, если *fp* не равен `None`.207208#### `[gettext.NullTranslations._parse]_parse(fp)`209210В базовом классе этот метод не выполняет никаких действий; он принимает файловый объект211212*fp*213214, читает из файла данные и инициализирует свой каталог сообщений. Если формат файла каталога сообщений не поддерживается, следует переопределить этот метод для разбора такого формата.215216#### `[gettext.NullTranslations.add_fallback]add_fallback(fallback)`217218Добавляет219220*fallback*221222в качестве запасного объекта для текущего объекта перевода. Объект перевода должен обращаться к запасному объекту, если он не может предоставить перевод для данного сообщения.223224#### `[gettext.NullTranslations.gettext]gettext(message)`225226Если установлен запасной вариант, перенаправить вызов227228[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)229230запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.231232#### `[gettext.NullTranslations.lgettext]lgettext(message)`233234Если установлен запасной вариант, перенаправить вызов235236[`lgettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.lgettext)237238запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.239240#### `[gettext.NullTranslations.ngettext]ngettext(singular, plural, n)`241242Если установлен запасной вариант, перенаправить вызов243244[`ngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.ngettext)245246запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.247248#### `[gettext.NullTranslations.lngettext]lngettext(singular, plural, n)`249250Если установлен запасной вариант, перенаправить вызов251252[`ngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.ngettext)253254запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.255256#### `[gettext.NullTranslations.info]info()`257258Возвращает «защищённую» переменную259260`_info`261262.263264#### `[gettext.NullTranslations.charset]charset()`265266Возвращает «защищённую» переменную267268`_charset`269270, которая является кодировкой файла каталога сообщений.271272#### `[gettext.NullTranslations.output_charset]output_charset()`273274Возвращает «защищённую» переменную275276`_output_charset`277278, которая определяет кодировку для возврата переведённых сообщений в методах279280[`lgettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.lgettext)281282и283284[`lngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.lngettext)285286.287288#### `[gettext.NullTranslations.set_output_charset]set_output_charset(charset)`289290Изменяет «защищённую» переменную291292`_output_charset`293294, которая определяет кодировку, используемую для возврата переведённых сообщений.295296#### `[gettext.NullTranslations.install]install([names])`297298Этот метод устанавливает `self.gettext()` во встроенное пространство имён, привязывая его к `_`.299300Если задан параметр *names*, он должен быть последовательностью, содержащей имена функций, которые вы хотите установить во встроенное пространство имён в дополнение к `_()`. Поддерживаемые имена: `'gettext'` (привязан к `self.gettext()`), `'ngettext'` (привязан к `self.ngettext()`), `'lgettext'` и `'lngettext'`.301302Обратите внимание, что это лишь один из способов, хоть и самый удобный, сделать функцию `_()` доступной в приложении. Поскольку это влияет на всё приложение глобально, и в особенности на встроенное пространство имён, локализованные модули никогда не должны устанавливать `_()`. Вместо этого им следует использовать следующий код, чтобы сделать `_()` доступной в своём модуле:303304```python305import gettext306t = gettext.translation('mymodule', ...)307_ = t.gettext308```309310Это помещает `_()` только в глобальное пространство имён модуля и поэтому влияет только на вызовы внутри этого модуля.311312### Класс `GNUTranslations`313314Модуль `gettext` предоставляет один дополнительный класс, производный от [`NullTranslations`](https://python-all.ru/3.0/library/gettext.html#gettext.NullTranslations): `GNUTranslations`. Этот класс переопределяет `_parse()` для чтения файлов формата GNU **gettext** `.mo` как в формате big-endian, так и в формате little-endian.315316`GNUTranslations` разбирает необязательные метаданные из каталога переводов. В GNU **gettext** принято включать метаданные как перевод пустой строки. Эти метаданные представлены парами [**RFC 822**](https://python-all.ru/3.0/library/gettext.html)-стиля `ключ: значение` и должны содержать ключ `Project-Id-Version`. Если найден ключ `Content-Type`, то свойство `charset` используется для инициализации «защищённой» переменной экземпляра `_charset`; по умолчанию `None`, если не найдена. Если кодировка charset указана, все идентификаторы сообщений и строки сообщений, прочитанные из каталога, преобразуются в Unicode с использованием этой кодировки; в противном случае предполагается кодировка ASCII.317318Поскольку идентификаторы сообщений также читаются как строки Unicode, все методы `*gettext()` будут считать идентификаторы сообщений строками Unicode, а не байтовыми строками.319320Весь набор пар ключ/значение помещается в словарь и устанавливается как «защищённая» переменная экземпляра `_info`.321322Если магическое число файла `.mo` неверно или при чтении файла возникают другие проблемы, создание экземпляра класса `GNUTranslations` может вызвать [`IOError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IOError).323324Следующие методы переопределены из реализации базового класса:325326#### `[gettext.GNUTranslations.gettext]GNUTranslations.gettext(message)`327328Ищет идентификатор329330*message*331332в каталоге и возвращает соответствующую строку сообщения в виде строки Unicode. Если в каталоге нет записи для идентификатора333334*message*335336и установлен запасной вариант, поиск передаётся методу337338[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)339340запасного объекта. В противном случае возвращается идентификатор341342*message*343344.345346#### `[gettext.GNUTranslations.lgettext]GNUTranslations.lgettext(message)`347348Эквивалентно349350[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)351352, но перевод возвращается в виде байтовой строки, закодированной в выбранной выходной кодировке, или в предпочтительной системной кодировке, если кодировка не была явно задана с помощью353354`set_output_charset()`355356.357358#### `[gettext.GNUTranslations.ngettext]GNUTranslations.ngettext(singular, plural, n)`359360Выполняет поиск формы множественного числа по идентификатору сообщения. *singular* используется как идентификатор сообщения для поиска в каталоге, а *n* используется для определения того, какую форму множественного числа использовать. Возвращаемая строка сообщения является строкой Unicode.361362Если идентификатор сообщения не найден в каталоге и указан запасной вариант, запрос передаётся методу [`ngettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.ngettext) запасного объекта. В противном случае, когда *n* равно 1, возвращается *singular*, а во всех остальных случаях – *plural*.363364Вот пример:365366```python367n = len(os.listdir('.'))368cat = GNUTranslations(somefile)369message = cat.ngettext(370    'There is %(num)d file in this directory',371    'There are %(num)d files in this directory',372    n) % {'num': n}373```374375#### `[gettext.GNUTranslations.lngettext]GNUTranslations.lngettext(singular, plural, n)`376377Эквивалентно378379[`gettext()`](https://python-all.ru/3.0/library/gettext.html#gettext.gettext)380381, но перевод возвращается в виде байтовой строки, закодированной в выбранной выходной кодировке, или в предпочтительной системной кодировке, если кодировка не была явно задана с помощью382383`set_output_charset()`384385.386387### Поддержка каталогов сообщений Solaris388389Операционная система Solaris определяет собственный двоичный формат файлов `.mo`, но, поскольку документации по этому формату найти не удалось, в настоящее время он не поддерживается.390391### Конструктор каталога392393GNOME использует версию модуля `gettext` от James Henstridge, но эта версия имеет несколько иной API. Её задокументированное использование было:394395```python396import gettext397cat = gettext.Catalog(domain, localedir)398_ = cat.gettext399print(_('hello world'))400```401402Для совместимости с этим более старым модулем функция `Catalog()` является псевдонимом для описанной выше функции [`translation()`](https://python-all.ru/3.0/library/gettext.html#gettext.translation).403404Одно различие между этим модулем и модулем Хенстриджа: его объекты каталога поддерживали доступ через API отображения (mapping API), но, по-видимому, эта возможность не используется и поэтому в настоящее время не поддерживается.405406## Интернационализация программ и модулей407408Интернационализация (I18N) – это процесс, благодаря которому программа начинает работать с несколькими языками. Локализация (L10N) – это адаптация уже интернационализированной программы к местному языку и культурным особенностям. Чтобы добавить в программу на Python поддержку нескольких языков, нужно выполнить следующие шаги:4094101. подготовить программу или модуль, специально помечая переводимые строки4112. запустить набор инструментов над размеченными файлами для создания исходных каталогов сообщений4123. создание языковых переводов каталогов сообщений4134. использовать модуль `gettext` для правильного перевода строк сообщений414415Чтобы подготовить код к интернационализации, нужно просмотреть все строки в своих файлах. Любую строку, которую требуется перевести, следует пометить, обернув её в вызов `_('...')` – то есть в функцию `_()`. Например:416417```python418filename = 'mylog.txt'419message = _('writing a log message')420fp = open(filename, 'w')421fp.write(message)422fp.close()423```424425В этом примере строка `'writing a log message'` помечена как кандидат на перевод, а строки `'mylog.txt'` и `'w'` – нет.426427Дистрибутив Python включает два инструмента, которые помогают создавать каталоги сообщений после подготовки исходного кода. Они могут быть доступны или не доступны в бинарном дистрибутиве, но их можно найти в дистрибутиве исходного кода, в каталоге `Tools/i18n`.428429Программа **pygettext** [\[3\]](https://python-all.ru/3.0/library/gettext.html#id8) сканирует весь исходный код Python в поиске строк, которые были ранее помечены как переводимые. Она похожа на программу GNU **gettext**, за исключением того, что понимает все тонкости исходного кода Python, но ничего не знает об исходном коде C или C++. GNU `gettext` не требуется, если только не переводится код на C (например, модули расширения на C).430431**pygettext** генерирует текстовые файлы каталогов сообщений в стиле Uniforum, удобочитаемые для человека – `.pot`, по сути структурированные файлы, которые содержат все помеченные строки в исходном коде вместе с заполнителем для строк перевода. **pygettext** – это скрипт командной строки, поддерживающий интерфейс, похожий на **xgettext**; подробнее о его использовании можно узнать, запустив:432433```python434pygettext.py --help435```436437Копии этих файлов `.pot` затем передаются индивидуальным переводчикам, которые пишут версии для каждого поддерживаемого естественного языка. Они возвращают заполненные версии для конкретного языка в виде файла `.po`. С помощью программы **msgfmt.py** [\[4\]](https://python-all.ru/3.0/library/gettext.html#id9) (в каталоге `Tools/i18n`) из файлов `.po`, полученных от переводчиков, генерируются машиночитаемые двоичные файлы каталогов `.mo`. Файлы `.mo` используются модулем `gettext` для непосредственной обработки перевода во время выполнения.438439Способ использования модуля `gettext` в коде зависит от того, выполняется ли интернационализация одного модуля или всего приложения. В следующих двух разделах будет рассмотрен каждый случай.440441### Локализация модуля442443Если вы локализуете свой модуль, позаботьтесь о том, чтобы не вносить глобальные изменения, например, в пространство встроенных имён. Не используйте GNU `gettext` API, а вместо этого применяйте API на основе классов.444445Предположим, ваш модуль называется «spam», и файлы перевода модуля для разных естественных языков в формате `.mo` находятся в каталоге `/usr/share/locale` в формате GNU **gettext**. Вот что нужно поместить в начало вашего модуля:446447```python448import gettext449t = gettext.translation('spam', '/usr/share/locale')450_ = t.lgettext451```452453### Локализация приложения454455Если вы локализуете приложение, можно установить функцию `_()` глобально во встроенное пространство имён, обычно в главном файле приложения. Тогда во всех файлах приложения можно будет использовать `_('...')` без явной установки в каждом из них.456457В простейшем случае нужно добавить в главный файл приложения следующий код:458459```python460import gettext461gettext.install('myapplication')462```463464Если нужно задать каталог локали, можно передать эти значения в функцию `install()`:465466```python467import gettext468gettext.install('myapplication', '/usr/share/locale')469```470471### Переключение языков на лету472473Если программа должна одновременно поддерживать много языков, можно создать несколько экземпляров перевода и переключаться между ними явно:474475```python476import gettext477478lang1 = gettext.translation('myapplication', languages=['en'])479lang2 = gettext.translation('myapplication', languages=['fr'])480lang3 = gettext.translation('myapplication', languages=['de'])481482# начните с использования language1483lang1.install()484485# ... проходит время, пользователь выбирает language 2486lang2.install()487488# ... проходит ещё больше времени, пользователь выбирает language 3489lang3.install()490```491492### Отложенные переводы493494В большинстве случаев строки переводятся там же, где и пишутся. Однако иногда нужно пометить строки для перевода, но отложить собственно перевод на потом. Классический пример:495496```python497animals = ['mollusk',498           'albatross',499           'rat',500           'penguin',501           'python', ]502# ...503for a in animals:504    print(a)505```506507Здесь требуется пометить строки в списке `animals` как переводимые, но не переводить их до момента вывода.508509Вот один из способов справиться с этим:510511```python512def _(message): return message513514animals = [_('mollusk'),515           _('albatross'),516           _('rat'),517           _('penguin'),518           _('python'), ]519520del _521522# ...523for a in animals:524    print(_(a))525```526527Это работает, потому что фиктивное определение `_()` просто возвращает строку без изменений. И это фиктивное определение временно переопределяет любое определение `_()` во встроенном пространстве имён (до выполнения команды [`del`](https://python-all.ru/3.0/reference/simple_stmts.html#del)). Следует соблюдать осторожность, если в локальном пространстве имён существует предыдущее определение `_()`.528529Обратите внимание, что второе использование `_()` не будет распознано программой **pygettext** как переводимое, поскольку это не строка.530531Другой способ – следующий пример:532533```python534def N_(message): return message535536animals = [N_('mollusk'),537           N_('albatross'),538           N_('rat'),539           N_('penguin'),540           N_('python'), ]541542# ...543for a in animals:544    print(_(a))545```546547В этом случае переводимые строки помечаются функцией `N_()`, [\[5\]](https://python-all.ru/3.0/library/gettext.html#id10) которая не конфликтует ни с одним определением `_()`. Однако потребуется научить программу извлечения сообщений искать переводимые строки, помеченные `N_()`. **pygettext** и **xpot** поддерживают это с помощью параметров командной строки.548549## Благодарности550551Следующие люди внесли код, отзывы, предложения по оформлению, предыдущие реализации и ценный опыт в создание этого модуля:552553- Peter Funk554- James Henstridge555- Juan David Ibáñez Palomar556- Marc-André Lemburg557- Martin von Löwis558- François Pinard559- Barry Warsaw560- Gustavo Niemeyer561562Сноски563564| [\[1\]](https://python-all.ru/3.0/library/gettext.html#id1) | Каталог локали по умолчанию зависит от системы; например, в RedHat Linux это `/usr/share/locale`, а в Solaris – `/usr/lib/locale`. Модуль `gettext` не пытается поддерживать эти системные значения по умолчанию; вместо этого его значением по умолчанию является `sys.prefix/share/locale`. По этой причине в начале приложения всегда лучше вызывать [`bindtextdomain()`](https://python-all.ru/3.0/library/gettext.html#gettext.bindtextdomain) с явным абсолютным путём. |565| --- | --- |566567| [\[2\]](https://python-all.ru/3.0/library/gettext.html#id2) | См. примечание к [`bindtextdomain()`](https://python-all.ru/3.0/library/gettext.html#gettext.bindtextdomain) выше. |568| --- | --- |569570| [\[3\]](https://python-all.ru/3.0/library/gettext.html#id3) | Франсуа Пинар написал программу под названием **xpot**, которая выполняет аналогичную задачу. Она доступна как часть его пакета **po-utils** по адресу http ://po-utils.progiciels-bpi.ca/. |571| --- | --- |572573| [\[4\]](https://python-all.ru/3.0/library/gettext.html#id4) | **msgfmt.py** двоично совместим с GNU **msgfmt**, за исключением того, что предоставляет более простую реализацию на чистом Python. С помощью этого и **pygettext.py** обычно не требуется устанавливать пакет GNU **gettext** для интернационализации приложений Python. |574| --- | --- |575576| [\[5\]](https://python-all.ru/3.0/library/gettext.html#id5) | Выбор `N_()` здесь абсолютно произволен; с тем же успехом это могло бы быть `MarkThisStringForTranslation()`. |577| --- | --- |578