JMANI

python 3.8 I18N gettext 본문

Python3/국제화ᆞ현지화

python 3.8 I18N gettext

jmani 2022. 5. 13. 10:21

gettext

docs: https://docs.python.org/ko/3.8/library/gettext.html

 

gettext — 다국어 국제화 서비스 — Python 3.8.13 문서

gettext 모듈은 파이썬 모듈과 응용 프로그램을 위한 국제화(I18N)와 현지화(L10N) 서비스를 제공합니다. GNU gettext 메시지 카탈로그 API와 파이썬 파일에 더 적합한 고수준 클래스 기반 API를 모두 지원

docs.python.org

 

1. create test.py

# test.py


'''
# File Structure

---test.py
---locale
   |---ko_KR
       |---LC_MESSAGES
           |---messages.mo
           |---messages.po
   |---messages.pot  
'''


import gettext

# python 3.7: 'ko_KR'
# >= python 3.8: ['ko_KR']
t = gettext.translation('messages', 'locale', ['ko_KR'])
_ = t.gettext

print(_('apple'))
print(_('banana'))

man = _("i")
verb = _("eat")
food = _("apple")
description = _("{man}{verb}{food}").format(man=man, verb=verb, food=food)

print(description)

apple

banana

ieatapple

 

2. create .pot

!mkdir locale
!pybabel extract test.py -o locale/messages.pot

mkdir: cannot create directory ‘locale’: File exists
extracting messages from test.py
writing PO template file to locale/messages.pot

!cat locale/messages.pot
# Translations template for PROJECT.
# Copyright (C) 2022 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2022-05-12 18:22+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.1\n"

#: test.py:6 test.py:11
msgid "apple"
msgstr "사과"

#: test.py:7
msgid "banana"
msgstr "바나나"

#: test.py:9
msgid "i"
msgstr "나"

#: test.py:10
msgid "eat"
msgstr "먹는다"

#: test.py:12
msgid "{man}{verb}{food}"
msgstr "{man}는 {food}를 {verb}."

 

3. msgstr "" 수정(번역)

 

4. compile > .po > .mo

!pybabel init -l ko_KR -i locale/messages.pot -d locale
!pybabel compile -f -d locale

creating catalog locale/ko_KR/LC_MESSAGES/messages.po based on locale/messages.pot
compiling catalog locale/ko_KR/LC_MESSAGES/messages.po to locale/ko_KR/LC_MESSAGES/messages.mo

 

5. 실행

!python3 test.py

사과
바나나
나는 사과를 먹는다.

 

Docs 해석

GNU gettext API > 현지화만 가능

gettext.bindtextdomain(domain, localedir=None)

  • localedir: localedir/language/LC_MESSAGES/domain.mo
  • localedir==None 이면, locale 언어로 번역

gettext.bind_textdomain_codeset(domain, codeset=None)

  • python 3.8이후로 codeset 안쓰임

gettext.textdomain(domain=None)

  • 도메인 변경 및 조회

gettext.gettext(message)

  • 현재 도메인, 언어, locale dir 기준으로 message 현지화 번역

gettext.dgettext(domain, message)

Like gettext(), but look the message up in the specified domain.

gettext.ngettext(singular, plural, n)

  • n으로 복수형 단수형 구분

Like gettext(), but consider plural forms. If a translation is found, apply the plural formula to n, and return the resulting message (some languages have more than two plural forms). If no translation is found, return singular if n is 1; return plural otherwise.

The Plural formula is taken from the catalog header. It is a C or Python expression that has a free variable n; the expression evaluates to the index of the plural in the catalog. See the GNU gettext documentation for the precise syntax to be used in .po files and the formulas for a variety of languages.

gettext.dngettext(domain, singular, plural, n)

Like ngettext(), but look the message up in the specified domain.

gettext.lgettext(message)

gettext.ldgettext(domain, message)

gettext.lngettext(singular, plural, n)

gettext.ldngettext(domain, singular, plural, n)

바이트 문자열 반환, python3에서는 지양

Here’s an example of typical usage for this API:

    import gettext
    gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
    gettext.textdomain('myapplication')
    _ = gettext.gettext
    # ...
    print(_('This is a translatable string.'))

클래스 기반 API >> 사용 중

gettext 모듈의 클래스 기반 API는 GNU gettext API보다 더 많은 유연성과 편리성을 제공합니다. 파이썬 응용 프로그램과 모듈을 현지화하는 권장되는 방법입니다. gettext는 GNU .mo 형식 파일의 구문 분석을 구현하고 문자열을 반환하는 메서드가 있는 GNUTranslations 클래스를 정의합니다. 이 클래스의 인스턴스는 내장 이름 공간에 함수 _()로 자신을 설치할 수도 있습니다.

gettext.find(domain, localedir=None, languages=None, all=False)

이 함수는 표준 .mo 파일 검색 알고리즘을 구현합니다. textdomain()이 취하는 것과 동일한 domain을 취합니다. 선택적 localedir은 bindtextdomain()에서와 같습니다. 선택적 languages는 문자열 리스트이며, 각 문자열은 언어 코드입니다.

localedir이 제공되지 않으면, 기본 시스템 로케일 디렉터리가 사용됩니다. 2 languages가 제공되지 않으면, 다음과 같은 환경 변수가 검색됩니다: LANGUAGE, LC_ALL, LC_MESSAGES 및 LANG. 비어 있지 않은 값을 반환하는 첫 번째 것이 languages 변수에 사용됩니다. 환경 변수는 콜론으로 구분된 언어 목록을 포함해야 하며, 콜론에서 분할되어 예상되는 언어 코드 문자열 리스트를 생성합니다.

그런 다음 find()는 언어를 확장하고 정규화한 다음, 다음 구성 요소로 구성된 기존 파일을 검색하면서, 이들을 이터레이트 합니다:

localedir/language/LC_MESSAGES/domain.mo

존재하는 첫 번째 파일 이름이 find()에 의해 반환됩니다. 그러한 파일이 없으면, None이 반환됩니다. all이 제공되면, 언어 리스트나 환경 변수에 나타나는 순서대로 모든 파일 이름의 리스트를 반환합니다.

gettext.translation(domain, localedir=None, languages=None, class_=None, fallback=False, codeset=None)

domain, localedir 및 languages를 기반으로 하는 *Translations 인스턴스를 반환합니다. 이 인스턴스는 연관된 .mo 파일 경로 리스트를 얻기 위해 먼저 find()로 전달됩니다. 동일한 .mo 파일 이름을 갖는 인스턴스는 캐시 됩니다. 인스턴스화되는 실제 클래스는 제공된다면 class_이고, 그렇지 않으면 GNUTranslations입니다. 클래스의 생성자는 단일 파일 객체 인자를 취해야 합니다. 제공되면, codeset은 lgettext()와 lngettext() 메서드에서 번역된 문자열을 인코딩하는 데 사용되는 문자 집합을 변경합니다.

여러 파일이 발견되면, 이후 파일은 이전 파일에 대한 폴 백으로 사용됩니다. 폴 백을 설정하는 것을 허락하기 위해, copy.copy()를 사용하여 캐시에서 각 번역 객체를 복제합니다; 실제 인스턴스 데이터는 여전히 캐시와 공유됩니다.

.mo 파일이 없으면, 이 함수는 fallback이 거짓(기본값)이면 OSError를 발생시키고, fallback이 참이면 NullTranslations 인스턴스를 반환합니다.

버전 3.3에서 변경: OSError 대신 IOError를 발생시킵니다.

  • python 3.8이후로 codeset 안쓰임

gettext.install(domain, localedir=None, codeset=None, names=None)

translation()에 전달되는 domain, localedir 및 codeset을 기반으로, 파이썬의 내장 이름 공간에 _() 함수를 설치합니다.

names 매개 변수에 대해서는, 번역 객체의 install() 메서드에 대한 설명을 참조하십시오.

아래에서 볼 수 있듯이, 일반적으로 다음과 같이 _() 함수에 대한 호출로 래핑하여, 응용 프로그램에 있는 번역 후보 문자열을 표시합니다:

print(_('This string will be translated.')) 편의상, _() 함수를 파이썬의 내장 이름 공간에 설치하여, 응용 프로그램의 모든 모듈에서 쉽게 액세스할 수 있도록 합니다.

  • python 3.8이후로 codeset 안쓰임

'Python3 > 국제화ᆞ현지화' 카테고리의 다른 글

python3.7 i18n gettext, gettext_windows  (0) 2022.04.29
Comments