SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
Интернационализация и локализация
          python-приложений
       с использованием gettext


      Александр Бельченко (bialix)


http://bialix.com/pycamp/gettext.pdf

                                      v.1.2
Вступительное слово

Это будет еще один доклад про Джанго
Это доклад про GUI desktop приложения.
Частично может быть применимо для web
Локализация нужна пользователям
Серебряной пули нет (и ложки тоже нет)
Пример одного из возможных вариантов
использования gettext. Мы используем его
в Bazaar GUI
Стандартный модуль gettext
          в Python

Предоставляет два вида API:
  Функции GNU gettext API
  Класс GNUTranslations
Функциональное API лишь обертка вокруг
классов; в общем случае работает несколько
медленнее
Функции gettext.py

Пара функций-переводчиков:
  gettext — перевод простых строк
  ngettext — перевод с выбором между
  единственным и множественным числом
Варианты функций с различными
префиксами:
  u — возвращает перевод как unicode строку
  l — перевод в нужной кодировке
  d — перевод ищется в указанном домене
Файлы с переводами

Где gettext ищет файлы переводов
(sys.prefix/share/locale):
  Linux: /usr/local/share/locale
  Windows: C:PythonXYsharelocale
Путь поиска можно указать вручную
Стандартная локация:
  Linux: /usr/share/locale
  Windows: ???
    {app}/locale
Язык пользователя


Язык для перевода:
  Можно указать вручную
  По умолчанию берется из переменных
  окружения:
  LANGUAGE, LC_ALL, LC_MESSAGES, LANG
    Эти переменные окружения отсутствуют на
    Windows (сюрприз-сюрприз!)
Кратко о GNU gettext, PO и MO

Библиотека общего назначения: годится для
консоли, GUI и web
Стандарт де-факто
  Существует развитая инфраструктура
  инструментов: специальные редакторы,
  поддержка в web-сервисах для перевода
Файлы:
  POT — шаблон для перевода
  PO — файлы перевода на конкретные языки
  MO — бинарные файлы перевода (runtime)
Формат PO-файлов

1) Заголовок файла (информация о
  переводчике, кодировка, выражение для
  множественного числа)
2) Тело файла состоит из записей вида:
     #: foo.py:3
     msgid "Hello"
     msgstr ""
Работа с GNU gettext утилитами
Сбор строк для перевода (py → pot):
  xgettext myapp.py myapplib/*.py -o myapp.pot
Создание файла перевода для конкретного
языка (pot → po):
  msginit -l ru -i myapp.pot -o myapp-ru.po
Трансляция в бинарный формат (po → mo):
  msgfmt -o locale/ru/LC_MESSAGES/myapp.mo
  myapp-ru.po
Обновление файлов с переводами (pot→po):
  msgmerge myapp-ru.po myapp.pot -o new.po
Python-утилиты
В стандартной поставке Python:
  pygettext.py
  msgfmt.py
В production использовать НЕ рекомендую
Единственное видимое достоинство
pygettext: умение извекать docstrings
Недостатки: не знает про ngettext, dgettext


Для Windows: http://gnuwin32.sf.net
Кавалерийская атака на танки
Документация на модуль gettext рекомендует
 очень простой способ включения:

import gettext
gettext.install('myapp', unicode=True)

В коде приложения не надо ничего
 импортировать и можно делать:

s = _('Hello, world!')

В чем подвох?
В чем подвох gettext.install

Такой короткий код нормально работает на
Linux и в большинстве случаев НЕ работает
на Windows
Нарушается принцип: явное лучше неявного
Перевод строк сразу «включается» для
языка пользователя (LANG)
  Что в свою очередь влияет на юнит-тесты, если
  вы проверяете строки
В чем подвох _()




       ?
Мы пойдём другим путём

Будем использовать функции и методы
модуля gettext напрямую и импортировать
имена явно
Включать перевод когда это нам нужно
Следовать уставу в чужом монастыре
Использование gettext
       в среде Windows
Кто украл $LANG? (Известно, кто)
locale.getdefaultlocale()[0]
Получение идентификатора локали LCID
(через pywin32 или ctypes):
  GetUserDefaultLCID()
  GetSystemDefaultLCID()
Преобразование LCID в строку при помощи
стандартного модуля locale:
  locale.windows_locale[lcid]
Пример готового кода

launchpad.net/gettext-py-windows

Кратко:

import ctypes, locale

lcid = ctypes.windll.kernel32.
       GetUserDefaultLCID()

lang = locale.windows_locale[lcid]
Использование методов gettext

Работаем с API класса(-ов) GNUTranslations:

import gettext as _gettext

_t = _gettext.NullTranslations()

_t = _gettext.translation('myapp',
                       localedir=xxx,
                       fallback=True)
Функции-переводчики
bzr branch lp:qbzr      (lib/i18n.py)


def gettext(s):
    return _t.ugettext(s)

def N_(s):
    return s


def ngettext(s, p, n):
    return _t.ungettext(s, p, n)
Использование в основном коде

import i18n
...
print i18n.gettext('Hello, world!')

Либо:

from i18n import gettext
...
print gettext('Hello, world!')
Выбор формы
       множественного числа
         «Найдено %d документов»

Английский:
 Found 1 document
 Found 2 documents

Русский:
 Найден 1 документ
 Найдено 2 документа
 Найдено 5 документов
Функция ngettext
Сигнатура: ngettext(singular, plural, number)

print ngettext('Found %d document',
    'Found %d documents', n) % n

POT-файл:

#: foo.py:7
#, python-format
msgid "Found %d document"
msgid_plural "Found %d documents"
msgstr[0] ""
msgstr[1] ""
gettext и unit-тесты
Всегда включать перевод явно для основного
режима и не включать для режима тестов

_t = _gettext.NullTranslations()

def install():
  global _t
  if sys.platform == 'win32':
     _check_win32_locale()
  _t = _gettext.translation('myapp',
         localedir=_get_locale_dir(),
         fallback=True)
Тестирование
     интернационализации

Используем специальный класс
ZzzTranslations(), который декорирует
строки
Включаем явно через командную строку:
  python myapp.py --zzz
Класс ZzzTranslations
class _ZzzTranslations(object):

 def zzz(self, s):
   return 'zz{{%s}}' % s

 def ugettext(self, s):
   return self.zzz(
                _null_t.ugettext(s))

 def ungettext(self, s, p, n):
   return self.zzz(
         _null_t.ungettext(s, p, n))
Инфраструктура проекта

Структура каталогов:

myapplib/
locale/            ← mo файлы
po/                ← pot, po файлы
myapp.py
setup.py

setup.py: build_pot, build_mo
Нужен ли перевод с дефолтного
        языка на английский?


●   Это не шутка, он реально нужен
    (LANG=en:ja)


●   Генерируется автоматически
    из POT-шаблона утилитой msginit
    либо msgen
Строки форматирования
Неправильно:
s = gettext('Page ' + number +
       ' of ' + count + ' pages')
s = gettext('Page %d of %d pages' %
             (number, count))
Плохо:
s = gettext('Page %d of %d pages') %
             (number, count)
Хорошо:
s = gettext('Page %(number)d of '
             '%(count)d pages') %
             dict(number=number,
                  count=count)
Web-сервисы для совместной
      работы над переводами

Один из сервисов: переводы на
https://translations.launchpad.net/

●Удобно для разработчиков: все языки в одном
месте

●Удобно для переводчиков: подсказки о
переводах таких же фраз из других проектов
Применение gettext в PyQt4?

 В собственном коде использовать gettext()
вместо tr()
 Формы/диалоги создаваемые в QtDesigner:
трансляция *.ui → ui_*.py
    используется скрипт для автоматической
      замены вызовов
      QtGui.QApplication.translate()
      на gettext()
Ссылки

GNU gettext: http://www.gnu.org/software/gettext

Утилиты для Windows:
http://gnuwin32.sf.net/packages/gettext.htm

Код поддержки gettext для Windows:
https://launchpad.net/gettext-py-windows

Примеры основаны на коде проектов:
https://launchpad.net/qbzr
https://launchpad.net/bzr-explorer

Weitere ähnliche Inhalte

Was ist angesagt?

C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееGetDev.NET
 
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)Badoo Development
 
язык программирования Go
язык программирования Goязык программирования Go
язык программирования GoMac'Kensi Lord
 
Ян Габис - RobotFramework: автоматизированое тестирование для всех
Ян Габис - RobotFramework: автоматизированое тестирование для всех Ян Габис - RobotFramework: автоматизированое тестирование для всех
Ян Габис - RobotFramework: автоматизированое тестирование для всех Minsk Linux User Group
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияcorehard_by
 
Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)IT-Доминанта
 
Как мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальКак мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальBadoo Development
 
Про асинхронное сетевое программирование
Про асинхронное сетевое программированиеПро асинхронное сетевое программирование
Про асинхронное сетевое программированиеPython Meetup
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Stas Vyschepan
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package managercorehard_by
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp
 
Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutinescorehard_by
 
Go в продакшене Яндекса: отчёт после года использования — Вячеслав Бахмутов
Go в продакшене Яндекса: отчёт после года использования — Вячеслав БахмутовGo в продакшене Яндекса: отчёт после года использования — Вячеслав Бахмутов
Go в продакшене Яндекса: отчёт после года использования — Вячеслав БахмутовYandex
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
Как ВКонтакте использует Go
Как ВКонтакте использует GoКак ВКонтакте использует Go
Как ВКонтакте использует GoArtem Kovardin
 

Was ist angesagt? (20)

C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущее
 
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
 
язык программирования Go
язык программирования Goязык программирования Go
язык программирования Go
 
Ян Габис - RobotFramework: автоматизированое тестирование для всех
Ян Габис - RobotFramework: автоматизированое тестирование для всех Ян Габис - RobotFramework: автоматизированое тестирование для всех
Ян Габис - RobotFramework: автоматизированое тестирование для всех
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюдения
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)
 
Как мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон ДовгальКак мы делаем модули PHP в Badoo – Антон Довгаль
Как мы делаем модули PHP в Badoo – Антон Довгаль
 
Про асинхронное сетевое программирование
Про асинхронное сетевое программированиеПро асинхронное сетевое программирование
Про асинхронное сетевое программирование
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package manager
 
Golang
GolangGolang
Golang
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный Python
 
iweb01
iweb01iweb01
iweb01
 
Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutines
 
Go в продакшене Яндекса: отчёт после года использования — Вячеслав Бахмутов
Go в продакшене Яндекса: отчёт после года использования — Вячеслав БахмутовGo в продакшене Яндекса: отчёт после года использования — Вячеслав Бахмутов
Go в продакшене Яндекса: отчёт после года использования — Вячеслав Бахмутов
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
Как ВКонтакте использует Go
Как ВКонтакте использует GoКак ВКонтакте использует Go
Как ВКонтакте использует Go
 

Andere mochten auch

This Month in Real Estate April 2011
This Month in Real Estate April 2011This Month in Real Estate April 2011
This Month in Real Estate April 2011pdrury
 
This Month in Real Estate November 2010
This Month in Real Estate November 2010This Month in Real Estate November 2010
This Month in Real Estate November 2010pdrury
 
T Mi Re April 2010 Us Edition
T Mi Re April 2010 Us EditionT Mi Re April 2010 Us Edition
T Mi Re April 2010 Us Editionpdrury
 
37101hunterstrail
37101hunterstrail37101hunterstrail
37101hunterstrailpdrury
 
John Savill - MRC Open Council Meeting 2011
 John Savill  - MRC Open Council Meeting 2011  John Savill  - MRC Open Council Meeting 2011
John Savill - MRC Open Council Meeting 2011 Medical Research Council
 
This Month in Real Estate - Sept 2011
This Month in Real Estate - Sept  2011This Month in Real Estate - Sept  2011
This Month in Real Estate - Sept 2011pdrury
 
TMiRe November15 Us
TMiRe November15 UsTMiRe November15 Us
TMiRe November15 Uspdrury
 

Andere mochten auch (8)

This Month in Real Estate April 2011
This Month in Real Estate April 2011This Month in Real Estate April 2011
This Month in Real Estate April 2011
 
Linked In Presentation
Linked In PresentationLinked In Presentation
Linked In Presentation
 
This Month in Real Estate November 2010
This Month in Real Estate November 2010This Month in Real Estate November 2010
This Month in Real Estate November 2010
 
T Mi Re April 2010 Us Edition
T Mi Re April 2010 Us EditionT Mi Re April 2010 Us Edition
T Mi Re April 2010 Us Edition
 
37101hunterstrail
37101hunterstrail37101hunterstrail
37101hunterstrail
 
John Savill - MRC Open Council Meeting 2011
 John Savill  - MRC Open Council Meeting 2011  John Savill  - MRC Open Council Meeting 2011
John Savill - MRC Open Council Meeting 2011
 
This Month in Real Estate - Sept 2011
This Month in Real Estate - Sept  2011This Month in Real Estate - Sept  2011
This Month in Real Estate - Sept 2011
 
TMiRe November15 Us
TMiRe November15 UsTMiRe November15 Us
TMiRe November15 Us
 

Ähnlich wie Internationalization and localization of the python applications with gettext by Alexander Belchenko

Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычностьStepan Tanasiychuk
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняAlexander Granin
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Rust - GDG DevFest 2016 Nizhny Novgorod
Rust - GDG DevFest 2016 Nizhny NovgorodRust - GDG DevFest 2016 Nizhny Novgorod
Rust - GDG DevFest 2016 Nizhny NovgorodNikita Baksalyar
 
инструменты веб разработчика
инструменты веб разработчикаинструменты веб разработчика
инструменты веб разработчикаSoftline
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
 
Software engineering seminars: git
 Software engineering seminars: git Software engineering seminars: git
Software engineering seminars: gitSemen Martynov
 
Git и GitHub для создания учебного контента
Git и GitHub для создания учебного контентаGit и GitHub для создания учебного контента
Git и GitHub для создания учебного контентаПупена Александр
 
Программирование под Maemo
Программирование под MaemoПрограммирование под Maemo
Программирование под Maemodmitryml
 
Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Denis Zakharov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Flame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеFlame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеКирилл Борисов
 
Теория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямТеория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямSergey Staroletov
 
игровая логика, проблемы и решения
игровая логика, проблемы и решенияигровая логика, проблемы и решения
игровая логика, проблемы и решенияВладимир Кожаев
 
Разработка сетевых приложений с gevent
Разработка сетевых приложений с geventРазработка сетевых приложений с gevent
Разработка сетевых приложений с geventAndrey Popp
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософияPaul Klimov
 

Ähnlich wie Internationalization and localization of the python applications with gettext by Alexander Belchenko (20)

Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычность
 
Git for you
Git for youGit for you
Git for you
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
php frameworks
php frameworksphp frameworks
php frameworks
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Rust - GDG DevFest 2016 Nizhny Novgorod
Rust - GDG DevFest 2016 Nizhny NovgorodRust - GDG DevFest 2016 Nizhny Novgorod
Rust - GDG DevFest 2016 Nizhny Novgorod
 
инструменты веб разработчика
инструменты веб разработчикаинструменты веб разработчика
инструменты веб разработчика
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
 
Software engineering seminars: git
 Software engineering seminars: git Software engineering seminars: git
Software engineering seminars: git
 
Git и GitHub для создания учебного контента
Git и GitHub для создания учебного контентаGit и GitHub для создания учебного контента
Git и GitHub для создания учебного контента
 
Программирование под Maemo
Программирование под MaemoПрограммирование под Maemo
Программирование под Maemo
 
Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Flame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеFlame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилирование
 
Теория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямТеория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциям
 
Кратко о Linux
Кратко о LinuxКратко о Linux
Кратко о Linux
 
игровая логика, проблемы и решения
игровая логика, проблемы и решенияигровая логика, проблемы и решения
игровая логика, проблемы и решения
 
Enter: legacy code
Enter: legacy codeEnter: legacy code
Enter: legacy code
 
Разработка сетевых приложений с gevent
Разработка сетевых приложений с geventРазработка сетевых приложений с gevent
Разработка сетевых приложений с gevent
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософия
 

Internationalization and localization of the python applications with gettext by Alexander Belchenko

  • 1. Интернационализация и локализация python-приложений с использованием gettext Александр Бельченко (bialix) http://bialix.com/pycamp/gettext.pdf v.1.2
  • 2. Вступительное слово Это будет еще один доклад про Джанго Это доклад про GUI desktop приложения. Частично может быть применимо для web Локализация нужна пользователям Серебряной пули нет (и ложки тоже нет) Пример одного из возможных вариантов использования gettext. Мы используем его в Bazaar GUI
  • 3. Стандартный модуль gettext в Python Предоставляет два вида API: Функции GNU gettext API Класс GNUTranslations Функциональное API лишь обертка вокруг классов; в общем случае работает несколько медленнее
  • 4. Функции gettext.py Пара функций-переводчиков: gettext — перевод простых строк ngettext — перевод с выбором между единственным и множественным числом Варианты функций с различными префиксами: u — возвращает перевод как unicode строку l — перевод в нужной кодировке d — перевод ищется в указанном домене
  • 5. Файлы с переводами Где gettext ищет файлы переводов (sys.prefix/share/locale): Linux: /usr/local/share/locale Windows: C:PythonXYsharelocale Путь поиска можно указать вручную Стандартная локация: Linux: /usr/share/locale Windows: ??? {app}/locale
  • 6. Язык пользователя Язык для перевода: Можно указать вручную По умолчанию берется из переменных окружения: LANGUAGE, LC_ALL, LC_MESSAGES, LANG Эти переменные окружения отсутствуют на Windows (сюрприз-сюрприз!)
  • 7. Кратко о GNU gettext, PO и MO Библиотека общего назначения: годится для консоли, GUI и web Стандарт де-факто Существует развитая инфраструктура инструментов: специальные редакторы, поддержка в web-сервисах для перевода Файлы: POT — шаблон для перевода PO — файлы перевода на конкретные языки MO — бинарные файлы перевода (runtime)
  • 8. Формат PO-файлов 1) Заголовок файла (информация о переводчике, кодировка, выражение для множественного числа) 2) Тело файла состоит из записей вида: #: foo.py:3 msgid "Hello" msgstr ""
  • 9. Работа с GNU gettext утилитами Сбор строк для перевода (py → pot): xgettext myapp.py myapplib/*.py -o myapp.pot Создание файла перевода для конкретного языка (pot → po): msginit -l ru -i myapp.pot -o myapp-ru.po Трансляция в бинарный формат (po → mo): msgfmt -o locale/ru/LC_MESSAGES/myapp.mo myapp-ru.po Обновление файлов с переводами (pot→po): msgmerge myapp-ru.po myapp.pot -o new.po
  • 10. Python-утилиты В стандартной поставке Python: pygettext.py msgfmt.py В production использовать НЕ рекомендую Единственное видимое достоинство pygettext: умение извекать docstrings Недостатки: не знает про ngettext, dgettext Для Windows: http://gnuwin32.sf.net
  • 11. Кавалерийская атака на танки Документация на модуль gettext рекомендует очень простой способ включения: import gettext gettext.install('myapp', unicode=True) В коде приложения не надо ничего импортировать и можно делать: s = _('Hello, world!') В чем подвох?
  • 12. В чем подвох gettext.install Такой короткий код нормально работает на Linux и в большинстве случаев НЕ работает на Windows Нарушается принцип: явное лучше неявного Перевод строк сразу «включается» для языка пользователя (LANG) Что в свою очередь влияет на юнит-тесты, если вы проверяете строки
  • 14. Мы пойдём другим путём Будем использовать функции и методы модуля gettext напрямую и импортировать имена явно Включать перевод когда это нам нужно Следовать уставу в чужом монастыре
  • 15. Использование gettext в среде Windows Кто украл $LANG? (Известно, кто) locale.getdefaultlocale()[0] Получение идентификатора локали LCID (через pywin32 или ctypes): GetUserDefaultLCID() GetSystemDefaultLCID() Преобразование LCID в строку при помощи стандартного модуля locale: locale.windows_locale[lcid]
  • 16. Пример готового кода launchpad.net/gettext-py-windows Кратко: import ctypes, locale lcid = ctypes.windll.kernel32. GetUserDefaultLCID() lang = locale.windows_locale[lcid]
  • 17. Использование методов gettext Работаем с API класса(-ов) GNUTranslations: import gettext as _gettext _t = _gettext.NullTranslations() _t = _gettext.translation('myapp', localedir=xxx, fallback=True)
  • 18. Функции-переводчики bzr branch lp:qbzr (lib/i18n.py) def gettext(s): return _t.ugettext(s) def N_(s): return s def ngettext(s, p, n): return _t.ungettext(s, p, n)
  • 19. Использование в основном коде import i18n ... print i18n.gettext('Hello, world!') Либо: from i18n import gettext ... print gettext('Hello, world!')
  • 20. Выбор формы множественного числа «Найдено %d документов» Английский: Found 1 document Found 2 documents Русский: Найден 1 документ Найдено 2 документа Найдено 5 документов
  • 21. Функция ngettext Сигнатура: ngettext(singular, plural, number) print ngettext('Found %d document', 'Found %d documents', n) % n POT-файл: #: foo.py:7 #, python-format msgid "Found %d document" msgid_plural "Found %d documents" msgstr[0] "" msgstr[1] ""
  • 22. gettext и unit-тесты Всегда включать перевод явно для основного режима и не включать для режима тестов _t = _gettext.NullTranslations() def install(): global _t if sys.platform == 'win32': _check_win32_locale() _t = _gettext.translation('myapp', localedir=_get_locale_dir(), fallback=True)
  • 23. Тестирование интернационализации Используем специальный класс ZzzTranslations(), который декорирует строки Включаем явно через командную строку: python myapp.py --zzz
  • 24. Класс ZzzTranslations class _ZzzTranslations(object): def zzz(self, s): return 'zz{{%s}}' % s def ugettext(self, s): return self.zzz( _null_t.ugettext(s)) def ungettext(self, s, p, n): return self.zzz( _null_t.ungettext(s, p, n))
  • 25.
  • 26. Инфраструктура проекта Структура каталогов: myapplib/ locale/ ← mo файлы po/ ← pot, po файлы myapp.py setup.py setup.py: build_pot, build_mo
  • 27. Нужен ли перевод с дефолтного языка на английский? ● Это не шутка, он реально нужен (LANG=en:ja) ● Генерируется автоматически из POT-шаблона утилитой msginit либо msgen
  • 28. Строки форматирования Неправильно: s = gettext('Page ' + number + ' of ' + count + ' pages') s = gettext('Page %d of %d pages' % (number, count)) Плохо: s = gettext('Page %d of %d pages') % (number, count) Хорошо: s = gettext('Page %(number)d of ' '%(count)d pages') % dict(number=number, count=count)
  • 29. Web-сервисы для совместной работы над переводами Один из сервисов: переводы на https://translations.launchpad.net/ ●Удобно для разработчиков: все языки в одном месте ●Удобно для переводчиков: подсказки о переводах таких же фраз из других проектов
  • 30. Применение gettext в PyQt4? В собственном коде использовать gettext() вместо tr() Формы/диалоги создаваемые в QtDesigner: трансляция *.ui → ui_*.py используется скрипт для автоматической замены вызовов QtGui.QApplication.translate() на gettext()
  • 31. Ссылки GNU gettext: http://www.gnu.org/software/gettext Утилиты для Windows: http://gnuwin32.sf.net/packages/gettext.htm Код поддержки gettext для Windows: https://launchpad.net/gettext-py-windows Примеры основаны на коде проектов: https://launchpad.net/qbzr https://launchpad.net/bzr-explorer