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

gettext.md

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

1> **Источник:** https://python-all.ru/3.2/library/gettext.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 22.1. [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) – Многоязычные службы интернационализации89**Исходный код:** [Lib/gettext.py](https://python-all.ru/src/3.2/Lib/gettext.py)1011---1213Модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) предоставляет службы интернационализации (I18N) и локализации (L10N) для модулей и приложений на Python. Он поддерживает как API каталогов сообщений GNU `gettext`, так и более высокоуровневый API на основе классов, который может быть более подходящим для файлов Python. Описанный ниже интерфейс позволяет писать сообщения модуля и приложения на одном естественном языке и предоставлять каталог переведённых сообщений для работы на разных естественных языках.1415Также даются некоторые советы по локализации модулей и приложений Python.1617## 22.1.1. GNU **gettext** API1819Модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) определяет следующий API, который очень похож на API GNU **gettext**. При использовании этого API перевод затрагивает всё приложение глобально. Часто это именно то, что нужно, если приложение является одноязычным, а выбор языка зависит от локали пользователя. Если же вы локализуете модуль Python или вашему приложению требуется переключать языки на лету, вероятно, лучше использовать API на основе классов.2021#### `gettext.bindtextdomain(domain, localedir=None)`2223Привязывает *domain* к каталогу локали *localedir*. Если точнее, [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) будет искать двоичные файлы `.mo` для указанного domain по пути (в Unix): `localedir/language/LC_MESSAGES/domain.mo`, где *languages* ищется в переменных окружения `LANGUAGE`, `LC_ALL`, `LC_MESSAGES` и `LANG` соответственно.2425Если *localedir* опущен или равен `None`, возвращается текущая привязка для *domain*. [\[1\]](https://python-all.ru/3.2/library/gettext.html#id6)2627#### `gettext.bind_textdomain_codeset(domain, codeset=None)`2829Привязывает *domain* к *codeset*, изменяя кодировку строк, возвращаемых семейством функций [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext). Если *codeset* опущен, возвращается текущая привязка.3031#### `gettext.textdomain(domain=None)`3233Изменяет или запрашивает текущий глобальный domain. Если *domain* равен `None`, возвращается текущий глобальный domain; в противном случае глобальный domain устанавливается в *domain*, который и возвращается.3435#### `gettext.gettext(message)`3637Возвращает локализованный перевод *message* на основе текущего глобального домена, языка и каталога локали. Эта функция обычно имеет псевдоним `_()` в локальном пространстве имён (см. примеры ниже).3839#### `gettext.lgettext(message)`4041Эквивалентно [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext), но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью [`bind_textdomain_codeset()`](https://python-all.ru/3.2/library/gettext.html#gettext.bind_textdomain_codeset).4243#### `gettext.dgettext(domain, message)`4445Как и [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext), но ищет сообщение в указанном *domain*.4647#### `gettext.ldgettext(domain, message)`4849Эквивалентно [`dgettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.dgettext), но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью [`bind_textdomain_codeset()`](https://python-all.ru/3.2/library/gettext.html#gettext.bind_textdomain_codeset).5051#### `gettext.ngettext(singular, plural, n)`5253Как и [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext), но учитывает формы множественного числа. Если перевод найден, применяет формулу множественного числа к *n* и возвращает результирующее сообщение (в некоторых языках более двух форм множественного числа). Если перевод не найден, возвращает *singular*, если *n* равно 1; в противном случае возвращает *plural*.5455Формула множественного числа берётся из заголовка каталога. Это выражение на C или Python с переменной *n*; выражение вычисляет индекс множественного числа в каталоге. Обратитесь к документации GNU gettext за точным синтаксисом, используемым в файлах `.po`, а также за формулами для разных языков.5657#### `gettext.lngettext(singular, plural, n)`5859Эквивалентно [`ngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.ngettext), но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью [`bind_textdomain_codeset()`](https://python-all.ru/3.2/library/gettext.html#gettext.bind_textdomain_codeset).6061#### `gettext.dngettext(domain, singular, plural, n)`6263Как и [`ngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.ngettext), но ищет сообщение в указанном *domain*.6465#### `gettext.ldngettext(domain, singular, plural, n)`6667Эквивалентно [`dngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.dngettext), но перевод возвращается в предпочтительной системной кодировке, если другая кодировка не была явно задана с помощью [`bind_textdomain_codeset()`](https://python-all.ru/3.2/library/gettext.html#gettext.bind_textdomain_codeset).6869Обратите внимание, что GNU **gettext** также определяет метод `dcgettext()`, но он был признан не полезным и поэтому в настоящее время не реализован.7071Вот пример типичного использования этого API:7273```python74import gettext75gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')76gettext.textdomain('myapplication')77_ = gettext.gettext78# ...79print(_('This is a translatable string.'))80```8182## 22.1.2. API на основе классов8384API на основе классов модуля [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) даёт больше гибкости и удобства, чем API GNU **gettext**. Это рекомендуемый способ локализации приложений и модулей Python. [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) определяет класс «translations», который реализует разбор файлов формата GNU `.mo` и имеет методы для возврата строк. Экземпляры этого класса «translations» также могут устанавливать себя во встроенное пространство имён в качестве функции `_()`.8586#### `gettext.find(domain, localedir=None, languages=None, all=False)`8788Эта функция реализует стандартный алгоритм поиска файлов `.mo`. Она принимает *domain*, такой же, как в [`textdomain()`](https://python-all.ru/3.2/library/gettext.html#gettext.textdomain). Необязательный *localedir* – как в [`bindtextdomain()`](https://python-all.ru/3.2/library/gettext.html#gettext.bindtextdomain). Необязательный *languages* – это список строк, где каждая строка – код языка.8990Если *localedir* не указан, используется системный каталог локалей по умолчанию. [\[2\]](https://python-all.ru/3.2/library/gettext.html#id7) Если *languages* не указан, то производится поиск среди следующих переменных окружения: `LANGUAGE`, `LC_ALL`, `LC_MESSAGES` и `LANG`. Первая из них, возвращающая непустое значение, используется для переменной *languages*. Переменные окружения должны содержать разделённый двоеточиями список языков, который будет разделён по двоеточиям для получения ожидаемого списка кодов языков.9192Затем [`find()`](https://python-all.ru/3.2/library/gettext.html#gettext.find) расширяет и нормализует языки и перебирает их в поисках существующего файла, построенного из следующих компонентов:9394`localedir/language/LC_MESSAGES/domain.mo`9596Первое из таких имён файлов, которое существует, возвращается функцией [`find()`](https://python-all.ru/3.2/library/gettext.html#gettext.find). Если такого файла нет, возвращается `None`. Если указан параметр *all*, возвращается список всех имён файлов в том порядке, в котором они встречаются в списке языков или в переменных окружения.9798#### `gettext.translation(domain, localedir=None, languages=None, class_=None, fallback=False, codeset=None)`99100Возвращает экземпляр `Translations` на основе *domain*, *localedir* и *languages*. Эти параметры сначала передаются в [`find()`](https://python-all.ru/3.2/library/gettext.html#gettext.find) для получения списка путей соответствующих файлов `.mo`. Экземпляры с одинаковыми именами файлов `.mo` кэшируются. Фактически создаётся экземпляр класса *class\_*, если он указан, иначе `GNUTranslations`. Конструктор класса должен принимать единственный аргумент [*file object*](https://python-all.ru/3.2/glossary.html#term-file-object). Если указан *codeset*, он изменит кодировку, используемую для кодирования переведённых строк в методах [`lgettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lgettext) и [`lngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lngettext).101102Если найдено несколько файлов, более поздние используются как запасные для более ранних. Чтобы разрешить установку запасного варианта, для клонирования каждого объекта перевода из кэша используется [`copy.copy()`](https://python-all.ru/3.2/library/copy.html#copy.copy); фактические данные экземпляра по-прежнему являются общими с кэшем.103104Если файл `.mo` не найден, эта функция возбуждает [`IOError`](https://python-all.ru/3.2/library/exceptions.html#IOError), если *fallback* имеет значение false (по умолчанию), и возвращает экземпляр [`NullTranslations`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations), если *fallback* равно true.105106#### `gettext.install(domain, localedir=None, codeset=None, names=None)`107108Эта функция устанавливает функцию `_()` во встроенное пространство имён Python на основе параметров *domain*, *localedir* и *codeset*, которые передаются функции [`translation()`](https://python-all.ru/3.2/library/gettext.html#gettext.translation).109110Для параметра *names* обратитесь к описанию метода [`install()`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations.install) объекта перевода.111112Как показано ниже, строки в приложении, предназначенные для перевода, обычно помечаются обёртыванием их в вызов функции `_()`, например:113114```python115print(_('This string will be translated.'))116```117118Для удобства функцию `_()` устанавливают в пространство имён встроенных функций Python, чтобы она была легко доступна во всех модулях приложения.119120### 22.1.2.1. Класс [`NullTranslations`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations)121122Классы перевода – это то, что фактически реализует перевод строк исходного сообщения в переведённые строки. Базовым классом, используемым всеми классами перевода, является [`NullTranslations`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations); он предоставляет базовый интерфейс, который можно использовать для написания собственных специализированных классов перевода. Ниже приведены методы класса [`NullTranslations`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations):123124#### `class gettext.NullTranslations(fp=None)`125126Принимает необязательный [*файловый объект*](https://python-all.ru/3.2/glossary.html#term-file-object) *fp*, который игнорируется базовым классом. Инициализирует «защищённые» переменные экземпляра *\_info* и *\_charset*, которые устанавливаются производными классами, а также *\_fallback*, который устанавливается через [`add_fallback()`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations.add_fallback). Затем вызывает `self._parse(fp)`, если *fp* не равен `None`.127128#### `_parse(fp)`129130В базовом классе этот метод не выполняет никаких действий; он принимает файловый объект *fp*, читает из файла данные и инициализирует свой каталог сообщений. Если формат файла каталога сообщений не поддерживается, следует переопределить этот метод для разбора такого формата.131132#### `add_fallback(fallback)`133134Добавляет *fallback* в качестве запасного объекта для текущего объекта перевода. Объект перевода должен обращаться к запасному объекту, если он не может предоставить перевод для данного сообщения.135136#### `gettext(message)`137138Если установлен запасной вариант, перенаправить вызов [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext) запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.139140#### `lgettext(message)`141142Если установлен запасной вариант, перенаправить вызов [`lgettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lgettext) запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.143144#### `ngettext(singular, plural, n)`145146Если установлен запасной вариант, перенаправить вызов [`ngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.ngettext) запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.147148#### `lngettext(singular, plural, n)`149150Если установлен запасной вариант, перенаправить вызов [`lngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lngettext) запасному объекту. В противном случае вернуть переведённое сообщение. Переопределяется в производных классах.151152#### `info()`153154Возвращает «защищённую» переменную `_info`.155156#### `charset()`157158Возвращает «защищённую» переменную `_charset`, которая является кодировкой файла каталога сообщений.159160#### `output_charset()`161162Возвращает «защищённую» переменную `_output_charset`, которая определяет кодировку для возврата переведённых сообщений в методах [`lgettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lgettext) и [`lngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.lngettext).163164#### `set_output_charset(charset)`165166Изменяет «защищённую» переменную `_output_charset`, которая определяет кодировку, используемую для возврата переведённых сообщений.167168#### `install(names=None)`169170Этот метод устанавливает `self.gettext()` во встроенное пространство имён, привязывая его к `_`.171172Если параметр *names* задан, это должна быть последовательность, содержащая имена функций, которые требуется установить в пространство имён builtins в дополнение к `_()`. Поддерживаемые имена: `'gettext'` (привязывается к `self.gettext()`), `'ngettext'` (привязывается к `self.ngettext()`), `'lgettext'` и `'lngettext'`.173174Обратите внимание, что это лишь один из способов, хоть и самый удобный, сделать функцию `_()` доступной в приложении. Поскольку это влияет на всё приложение глобально, и в особенности на встроенное пространство имён, локализованные модули никогда не должны устанавливать `_()`. Вместо этого им следует использовать следующий код, чтобы сделать `_()` доступной в своём модуле:175176```python177import gettext178t = gettext.translation('mymodule', ...)179_ = t.gettext180```181182Это помещает `_()` только в глобальное пространство имён модуля и поэтому влияет только на вызовы внутри этого модуля.183184### 22.1.2.2. Класс `GNUTranslations`185186Модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) предоставляет один дополнительный класс, производный от [`NullTranslations`](https://python-all.ru/3.2/library/gettext.html#gettext.NullTranslations): `GNUTranslations`. Этот класс переопределяет `_parse()` для чтения файлов GNU **gettext** формата `.mo` как в big-endian, так и в little-endian формате.187188`GNUTranslations` разбирает необязательные метаданные из каталога переводов. В GNU **gettext** принято включать метаданные как перевод пустой строки. Эти метаданные представлены парами [**RFC 822**](https://python-all.ru/3.2/library/gettext.html)-стиля `ключ: значение` и должны содержать ключ `Project-Id-Version`. Если найден ключ `Content-Type`, то свойство `charset` используется для инициализации «защищённой» переменной экземпляра `_charset`; по умолчанию `None`, если не найдена. Если кодировка charset указана, все идентификаторы сообщений и строки сообщений, прочитанные из каталога, преобразуются в Unicode с использованием этой кодировки; в противном случае предполагается кодировка ASCII.189190Поскольку идентификаторы сообщений также читаются как строки Unicode, все методы `*gettext()` будут считать идентификаторы сообщений строками Unicode, а не байтовыми строками.191192Весь набор пар ключ/значение помещается в словарь и устанавливается как «защищённая» переменная экземпляра `_info`.193194Если магическое число файла `.mo` неверно или при чтении файла возникают другие проблемы, создание экземпляра класса `GNUTranslations` может вызвать [`IOError`](https://python-all.ru/3.2/library/exceptions.html#IOError).195196Следующие методы переопределены из реализации базового класса:197198#### `GNUTranslations.gettext(message)`199200Ищет идентификатор *message* в каталоге и возвращает соответствующую строку сообщения в виде строки Unicode. Если в каталоге нет записи для идентификатора *message* и установлен запасной вариант, поиск передаётся методу [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext) запасного объекта. В противном случае возвращается идентификатор *message*.201202#### `GNUTranslations.lgettext(message)`203204Эквивалентно [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext), но перевод возвращается в виде байтовой строки, закодированной в выбранной выходной кодировке, или в предпочтительной системной кодировке, если кодировка не была явно задана с помощью `set_output_charset()`.205206#### `GNUTranslations.ngettext(singular, plural, n)`207208Выполняет поиск формы множественного числа по идентификатору сообщения. *singular* используется как идентификатор сообщения для поиска в каталоге, а *n* используется для определения того, какую форму множественного числа использовать. Возвращаемая строка сообщения является строкой Unicode.209210Если идентификатор сообщения не найден в каталоге и указан запасной вариант, запрос передаётся методу [`ngettext()`](https://python-all.ru/3.2/library/gettext.html#gettext.ngettext) запасного объекта. В противном случае, когда *n* равно 1, возвращается *singular*, а во всех остальных случаях – *plural*.211212Вот пример:213214```python215n = len(os.listdir('.'))216cat = GNUTranslations(somefile)217message = cat.ngettext(218    'There is %(num)d file in this directory',219    'There are %(num)d files in this directory',220    n) % {'num': n}221```222223#### `GNUTranslations.lngettext(singular, plural, n)`224225Эквивалентно [`gettext()`](https://python-all.ru/3.2/library/gettext.html#module-gettext), но перевод возвращается в виде байтовой строки, закодированной в выбранной выходной кодировке, или в предпочтительной системной кодировке, если кодировка не была явно задана с помощью `set_output_charset()`.226227### 22.1.2.3. Поддержка каталогов сообщений Solaris228229Операционная система Solaris определяет собственный двоичный формат файлов `.mo`, но, поскольку документации по этому формату найти не удалось, в настоящее время он не поддерживается.230231### 22.1.2.4. Конструктор Catalog232233В GNOME используется версия модуля [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) от Джеймса Хенстриджа, но эта версия имеет несколько иной API. Её задокументированное использование было:234235```python236import gettext237cat = gettext.Catalog(domain, localedir)238_ = cat.gettext239print(_('hello world'))240```241242Для совместимости с этим более старым модулем функция `Catalog()` является псевдонимом для описанной выше функции [`translation()`](https://python-all.ru/3.2/library/gettext.html#gettext.translation).243244Одно различие между этим модулем и модулем Хенстриджа: его объекты каталога поддерживали доступ через API отображения (mapping API), но, по-видимому, эта возможность не используется и поэтому в настоящее время не поддерживается.245246## 22.1.3. Интернационализация программ и модулей247248Интернационализация (I18N) – это процесс, благодаря которому программа начинает работать с несколькими языками. Локализация (L10N) – это адаптация уже интернационализированной программы к местному языку и культурным особенностям. Чтобы добавить в программу на Python поддержку нескольких языков, нужно выполнить следующие шаги:2492501. подготовить программу или модуль, специально помечая переводимые строки2512. запустить набор инструментов над размеченными файлами для создания исходных каталогов сообщений2523. создание языковых переводов каталогов сообщений2534. используйте модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext), чтобы строки сообщений были правильно переведены254255Чтобы подготовить код к интернационализации, нужно просмотреть все строки в своих файлах. Любую строку, которую требуется перевести, следует пометить, обернув её в вызов `_('...')` – то есть в функцию `_()`. Например:256257```python258filename = 'mylog.txt'259message = _('writing a log message')260fp = open(filename, 'w')261fp.write(message)262fp.close()263```264265В этом примере строка `'writing a log message'` помечена как кандидат на перевод, а строки `'mylog.txt'` и `'w'` – нет.266267Дистрибутив Python включает два инструмента, которые помогают создавать каталоги сообщений после подготовки исходного кода. Они могут быть доступны или не доступны в бинарном дистрибутиве, но их можно найти в дистрибутиве исходного кода, в каталоге `Tools/i18n`.268269Программа **pygettext** [\[3\]](https://python-all.ru/3.2/library/gettext.html#id8) сканирует весь исходный код Python в поиске строк, которые были ранее помечены как переводимые. Она похожа на программу GNU **gettext**, за исключением того, что понимает все тонкости исходного кода Python, но ничего не знает об исходном коде C или C++. GNU `gettext` не требуется, если только не переводится код на C (например, модули расширения на C).270271**pygettext** генерирует текстовые файлы каталогов сообщений в стиле Uniforum, удобочитаемые для человека – `.pot`, по сути структурированные файлы, которые содержат все помеченные строки в исходном коде вместе с заполнителем для строк перевода. **pygettext** – это скрипт командной строки, поддерживающий интерфейс, похожий на **xgettext**; подробнее о его использовании можно узнать, запустив:272273```python274pygettext.py --help275```276277Копии этих `.pot` файлов затем передаются отдельным переводчикам, которые создают версии для каждого поддерживаемого естественного языка. Они возвращают заполненные языковые версии в виде файла `.po`. С помощью программы **msgfmt.py** [\[4\]](https://python-all.ru/3.2/library/gettext.html#id9) (из каталога `Tools/i18n`) файлы `.po` от переводчиков преобразуются в машиночитаемые бинарные файлы каталогов `.mo`. Файлы `.mo` используются модулем [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) для обработки перевода во время выполнения.278279То, как вы используете модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) в своём коде, зависит от того, интернационализируете ли вы один модуль или всё приложение. В следующих двух разделах рассматривается каждый случай.280281### 22.1.3.1. Локализация модуля282283Если вы локализуете свой модуль, позаботьтесь о том, чтобы не вносить глобальные изменения, например, в пространство встроенных имён. Не используйте GNU `gettext` API, а вместо этого применяйте API на основе классов.284285Предположим, ваш модуль называется «spam», и файлы перевода модуля для разных естественных языков в формате `.mo` находятся в каталоге `/usr/share/locale` в формате GNU **gettext**. Вот что нужно поместить в начало вашего модуля:286287```python288import gettext289t = gettext.translation('spam', '/usr/share/locale')290_ = t.lgettext291```292293### 22.1.3.2. Локализация приложения294295Если вы локализуете приложение, можно установить функцию `_()` глобально во встроенное пространство имён, обычно в главном файле приложения. Тогда во всех файлах приложения можно будет использовать `_('...')` без явной установки в каждом из них.296297В простейшем случае нужно добавить в главный файл приложения следующий код:298299```python300import gettext301gettext.install('myapplication')302```303304Если требуется задать каталог локали, его можно передать в функцию [`install()`](https://python-all.ru/3.2/library/gettext.html#gettext.install):305306```python307import gettext308gettext.install('myapplication', '/usr/share/locale')309```310311### 22.1.3.3. Смена языка на лету312313Если программа должна одновременно поддерживать много языков, можно создать несколько экземпляров перевода и переключаться между ними явно:314315```python316import gettext317318lang1 = gettext.translation('myapplication', languages=['en'])319lang2 = gettext.translation('myapplication', languages=['fr'])320lang3 = gettext.translation('myapplication', languages=['de'])321322# начните с использования language1323lang1.install()324325# ... проходит время, пользователь выбирает language 2326lang2.install()327328# ... проходит ещё больше времени, пользователь выбирает language 3329lang3.install()330```331332### 22.1.3.4. Отложенные переводы333334В большинстве случаев строки переводятся там же, где и пишутся. Однако иногда нужно пометить строки для перевода, но отложить собственно перевод на потом. Классический пример:335336```python337animals = ['mollusk',338           'albatross',339           'rat',340           'penguin',341           'python', ]342# ...343for a in animals:344    print(a)345```346347Здесь требуется пометить строки в списке `animals` как переводимые, но не переводить их до момента вывода.348349Вот один из способов справиться с этим:350351```python352def _(message): return message353354animals = [_('mollusk'),355           _('albatross'),356           _('rat'),357           _('penguin'),358           _('python'), ]359360del _361362# ...363for a in animals:364    print(_(a))365```366367Это работает, потому что фиктивное определение `_()` просто возвращает строку без изменений. И это фиктивное определение временно переопределяет любое определение `_()` во встроенном пространстве имён (до выполнения команды [`del`](https://python-all.ru/3.2/reference/simple_stmts.html#del)). Следует соблюдать осторожность, если в локальном пространстве имён существует предыдущее определение `_()`.368369Обратите внимание, что второе использование `_()` не будет распознано программой **pygettext** как переводимое, поскольку это не строка.370371Другой способ – следующий пример:372373```python374def N_(message): return message375376animals = [N_('mollusk'),377           N_('albatross'),378           N_('rat'),379           N_('penguin'),380           N_('python'), ]381382# ...383for a in animals:384    print(_(a))385```386387В этом случае переводимые строки помечаются функцией `N_()`, [\[5\]](https://python-all.ru/3.2/library/gettext.html#id10) которая не конфликтует ни с одним определением `_()`. Однако потребуется научить программу извлечения сообщений искать переводимые строки, помеченные `N_()`. **pygettext** и **xpot** поддерживают это с помощью параметров командной строки.388389## 22.1.4. Благодарности390391Следующие люди внесли код, отзывы, предложения по оформлению, предыдущие реализации и ценный опыт в создание этого модуля:392393- Peter Funk394- James Henstridge395- Juan David Ibáñez Palomar396- Marc-André Lemburg397- Martin von Löwis398- François Pinard399- Barry Warsaw400- Gustavo Niemeyer401402Сноски403404| [\[1\]](https://python-all.ru/3.2/library/gettext.html#id1) | Каталог локали по умолчанию зависит от системы; например, в RedHat Linux это `/usr/share/locale`, а в Solaris – `/usr/lib/locale`. Модуль [`gettext`](https://python-all.ru/3.2/library/gettext.html#module-gettext) не пытается поддерживать эти системно-зависимые значения по умолчанию; вместо этого его значением по умолчанию является `sys.prefix/share/locale`. По этой причине в начале приложения всегда лучше вызывать [`bindtextdomain()`](https://python-all.ru/3.2/library/gettext.html#gettext.bindtextdomain) с явным абсолютным путём. |405| --- | --- |406407| [\[2\]](https://python-all.ru/3.2/library/gettext.html#id2) | См. примечание к [`bindtextdomain()`](https://python-all.ru/3.2/library/gettext.html#gettext.bindtextdomain) выше. |408| --- | --- |409410| [\[3\]](https://python-all.ru/3.2/library/gettext.html#id3) | Франсуа Пинар написал программу под названием **xpot**, которая выполняет схожую работу. Она входит в состав его [пакета po-utils](https://python-all.ru/3.2/library/gettext.html). |411| --- | --- |412413| [\[4\]](https://python-all.ru/3.2/library/gettext.html#id4) | **msgfmt.py** двоично совместим с GNU **msgfmt**, за исключением того, что предоставляет более простую реализацию на чистом Python. С помощью этого и **pygettext.py** обычно не требуется устанавливать пакет GNU **gettext** для интернационализации приложений Python. |414| --- | --- |415416| [\[5\]](https://python-all.ru/3.2/library/gettext.html#id5) | Выбор `N_()` здесь абсолютно произволен; с тем же успехом это могло бы быть `MarkThisStringForTranslation()`. |417| --- | --- |418