Найти - Пользователи
Полная версия: про gettext и про windows
Начало » Python для экспертов » про gettext и про windows
1 2
bialix
Я сделал анонс своей статьи в LJ: http://community.livejournal.com/ru_python/120316.html
LJ-юзер balu (в миру Михаил Казарян) ответил в комментах, что он писал похожее, и оно тоже опубликована на этом же сайте: http://python.com.ua/doc/inter.html

Хочу продолжить дискуссию здесь.
Во-превых, хочу сделать краткий анализ примера из статьи Михаила:


#!/usr/bin/python
# -*- coding: koi8-u -*-

import gettext, traceback

#Support internationalisation
try:
fp = open('./locale/uk/LC_MESSAGES/messages.mo', “rb”)
messages = gettext.GNUTranslations(fp)
fp.close()
except:
traceback.print_exc()
messages = gettext.NullTranslations()
messages.install(unicode=True)

domain = ‘test’ # Назва поточного домену (їх може
# бути декілька).
gettext.bindtextdomain(domain)# Прив'язуємо домен до каталогу з
# перекладом
gettext.textdomain(domain) #Встановлюємо поточний домен
_ = messages.ugettext #Перекладаємо текст
print _('Hello, world')+' string without translate'


Здесь имеется путаница class-based API и GNU gettext API, которые я упоминал в сворей статье. Однако – это лишь информационный шум, потому что реально работает только class-based API, потому что везде в коде используется экземпляр класса
messages = gettext.GNUTranslations(fp) либо messages = gettext.NullTranslations().

Что здесь делают вызовы GNU gettext API – решительно непонятно, поскольку к тому моменту они уже ни на что не влияют. Предположу, что это артефакты из другого старого кода.

Также видно, что Михаил загружает файл перевода вручную, при помощи намертво прошитого пути к MO-файлу. Это немного отличается от изложенного в моей статье. Михаил обещать найти и показать, как оно на самом деле у него работает в винде, жду с нетерпением.

Здесь в примере: ./locale/ua/LC_MESSAGES/messages.po
должно быть uk вместо ua.

И еще: если статья будет подвергаться коррекциям: слово “выддаю” по-украински пишется как “виддаю”. Плюс ще низка маленьких помилок, якщо є бажання – пройдіться якойсь програмою для перевірки орфографії.
balu
bialix
Здесь имеется путаница class-based API и GNU gettext API, которые я упоминал в сворей статье.
Ну да, есть разница в их использовании. И что из этого? Я описал тот метод, который мне удобнее, вы описали тот метод, который удобнее вам. Работают оба метода. Все рады, все гогочут ;)

bialix
Также видно, что Михаил загружает файл перевода вручную, при помощи намертво прошитого пути к MO-файлу.
На самом деле полный путь к файлу здесь прописан для ясности. В рабочих программах он, разумеется, генерируется в зависимости от языка, выбранного пользователем, независимо от локали.
bialix
Здесь в примере: ./locale/ua/LC_MESSAGES/messages.po
должно быть uk вместо ua.
Да, спасибо за замечание. В оригинале исправлю. Хотя приведенный код - работает, и содержит “uk”
bialix
если статья будет подвергаться коррекциям: слово “выддаю” по-украински пишется как “виддаю”;)
Ні, вірно буде “віддаю”. Винен, не замітив вчасно, що працював з російською розкладкою ;).
Обов'язково виправлю в оригіналі ;).

В ЖЖ я обещал указать, как определять локаль без использования win32api. Очень просто.

>>> import locale
>>> locale.getdefaultlocale()
('ru_RU', ‘cp1251’)
#Linux code
>>> locale.getdefaultlocale()

bialix
balu
bialix
Здесь имеется путаница class-based API и GNU gettext API, которые я упоминал в сворей статье.
Ну да, есть разница в их использовании. И что из этого? Я описал тот метод, который мне удобнее, вы описали тот метод, который удобнее вам. Работают оба метода. Все рады, все гогочут ;)
Да нет, никто не рад, и никто не гогочет. Вы пишите статью, которую будут читать люди и использовать ее как пример. И даете неправильные примеры. Я считаю – что это не есть гут.

balu
bialix
Также видно, что Михаил загружает файл перевода вручную, при помощи намертво прошитого пути к MO-файлу.
На самом деле полный путь к файлу здесь прописан для ясности. В рабочих программах он, разумеется, генерируется в зависимости от языка, выбранного пользователем, независимо от локали.
Так почему было не показать в своей статье правильный путь использования, без явного указания имени файла?

balu
В ЖЖ я обещал указать, как определять локаль без использования win32api. Очень просто.

>>> import locale
>>> locale.getdefaultlocale()
('ru_RU', ‘cp1251’)
#Linux code
>>> locale.getdefaultlocale()

Спасибо. Работает. Я готов подправить код в своих примерах, хотя отлавливание русской винды при установленном украинском языке пользователя мне лично очень даже нравится.
balu
bialix
Вы пишите статью, которую будут читать люди и использовать ее как пример. И даете неправильные примеры. Я считаю – что это не есть гут.
Что тут неправильного?
bialix
Так почему было не показать в своей статье правильный путь использования, без явного указания имени файла?
Ибо умному - достаточно. И я считал, что это само-собой разумеется ;)
bialix
balu
bialix
Вы пишите статью, которую будут читать люди и использовать ее как пример. И даете неправильные примеры. Я считаю – что это не есть гут.
Что тут неправильного?
Вы осознаете, что ваш пример содержит лишние строки? И что он эквивалентен следующему коду:


#!/usr/bin/python
# -*- coding: koi8-u -*-

import gettext, traceback

#Support internationalisation
try:
fp = open('./locale/uk/LC_MESSAGES/messages.mo', “rb”)
messages = gettext.GNUTranslations(fp)
fp.close()
except:
traceback.print_exc()
messages = gettext.NullTranslations()
messages.install(unicode=True)

print _('Hello, world')+' string without translate'


А еще лучше было бы обойтись без явной загрузки файла и без отлавливания исключения, и показать как оно в боевой системе должно работать. Но об этом уже говорилось.

balu
bialix
Так почему было не показать в своей статье правильный путь использования, без явного указания имени файла?
Ибо умному - достаточно. И я считал, что это само-собой разумеется ;)
Sapienti – sat.
Известная отмазка.
Дальнейшую дискуссию считаю бессмысленной.
balu
bialix
Вы осознаете, что ваш пример содержит лишние строки? И что он эквивалентен следующему коду:
Да, спасибо. Строки
gettext.bindtextdomain(domain)
gettext.textdomain(domain)
действительно пережиток старого кода и в данном конкретном примере лишние. Исправлю.
(Хотя доменов может быть несколько, для того и строка gettext.textdomain(domain) )
И еще:
bialix
Что здесь делают вызовы GNU gettext API – решительно непонятно, поскольку к тому моменту они уже ни на что не влияют.
gettext.GNUTranslations и gettext.NullTranslations используются т.к. имеют метод ugettext. Разница между ним и gettext в том, что ugettext возвращает перевод в виде юникода.

Иначе можно обойтись кодом :

domain = ‘test’
gettext.bindtextdomain(domain, ‘./locale’)
gettext.textdomain(domain)
_ = gettext.gettext
balu
bialix
Sapienti – sat.
Известная отмазка.
Ладно, например, так:

import os, sys
#Для локального варианта
path = lambda x: ‘./locale/’+x+'/LC_MESSAGES/filename.mo'
#Для стабильного релиза:
path = lambda x: os.path.join(sys.prefix+'/share/locale/'+x+'/LC_MESSAGES','filename.mo')
your_path=path('uk')
fp = open(your_path, ‘r’)
bialix
balu
bialix
Sapienti – sat.
Известная отмазка.
Ладно, например, так:

import os, sys
#Для локального варианта
path = lambda x: ‘./locale/’+x+'/LC_MESSAGES/filename.mo'
#Для стабильного релиза:
path = lambda x: os.path.join(sys.prefix+'/share/locale/'+x+'/LC_MESSAGES','filename.mo')
your_path=path('uk')
fp = open(your_path, ‘r’)
Зачем вообще руками открывать файл?
Я у себя в коде делаю так:


import gettext

d = os.path.join(os.path.realpath(os.path.dirname(sys.argv)), ‘locale’)
if not os.path.isdir(d):
d = None

gettext.install('bzrconf', d, True)


Файл будет открыт самостоятельно во время выполнения gettext.install.
При этом будет выбрана либо локальная папка с MO-файлами, либо sys.prefix/share/locale (по умолчанию, когда d = None)
balu
bialix
Зачем вообще руками открывать файл?
Я у себя в коде делаю так:


import gettext

d = os.path.join(os.path.realpath(os.path.dirname(sys.argv)), ‘locale’)
if not os.path.isdir(d):
d = None

gettext.install('bzrconf', d, True)


Файл будет открыт самостоятельно во время выполнения gettext.install.
При этом будет выбрана либо локальная папка с MO-файлами, либо sys.prefix/share/locale (по умолчанию, когда d = None)
Да, можно и так. Плюс locale.setlocale(нужная локаль).
Остается проблема с перекодированием в юникод, но это из немного другой оперы.
bialix
balu
bialix
Зачем вообще руками открывать файл?
Я у себя в коде делаю так:


import gettext

d = os.path.join(os.path.realpath(os.path.dirname(sys.argv)), ‘locale’)
if not os.path.isdir(d):
d = None

gettext.install('bzrconf', d, True)


Файл будет открыт самостоятельно во время выполнения gettext.install.
При этом будет выбрана либо локальная папка с MO-файлами, либо sys.prefix/share/locale (по умолчанию, когда d = None)
Да, можно и так. Плюс locale.setlocale(нужная локаль).
Остается проблема с перекодированием в юникод, но это из немного другой оперы.
1) locale.setlocale насколько я могу судить не имеет никакого эффекта под windows.
2) Никаких проблем с перекодированием в юникод не возникает, потому что я указал флаг unicode=True (у меня в коде это просто True, у вас в коде это message.install(1) ), которое заставляет инсталлировать метод ugettext как _
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB