gettext — 다국어 국제화 서비스

소스 코드: Lib/gettext.py


gettext 모듈은 파이썬 모듈과 응용 프로그램을 위한 국제화(I18N)와 현지화(L10N) 서비스를 제공합니다. GNU gettext 메시지 카탈로그 API와 파이썬 파일에 더 적합한 고수준 클래스 기반 API를 모두 지원합니다. 아래 설명된 인터페이스를 사용하면 모듈과 응용 프로그램 메시지를 하나의 자연어로 작성하고, 다른 자연어로 실행하기 위해 번역된 메시지 카탈로그를 제공할 수 있습니다.

파이썬 모듈과 응용 프로그램을 현지화하는 데 대한 힌트도 제공됩니다.

GNU gettext API

gettext 모듈은 GNU gettext API와 매우 유사한 다음 API를 정의합니다. 이 API를 사용하면 전체 응용 프로그램의 번역에 전역적으로 영향을 미칩니다. 응용 프로그램이 단일 언어라면 사용자의 로케일에 따라 언어를 선택할 수 있는 것과 함께 종종 이것이 여러분이 원하는 것입니다. 파이썬 모듈을 현지화하거나, 응용 프로그램에서 언어를 실행 중에 전환해야 한다면, 아마도 클래스 기반 API를 대신 사용하고 싶을 것입니다.

gettext.bindtextdomain(domain, localedir=None)

domain을 로케일 디렉터리 localedir에 바인드합니다. 보다 구체적으로, gettext는 경로 (유닉스에서) localedir/language/LC_MESSAGES/domain.mo를 사용하여 지정된 도메인(domain)에 대한 바이너리 .mo 파일을 찾습니다. 여기서 language는 환경 변수 LANGUAGE, LC_ALL, LC_MESSAGESLANG에서 각각 검색됩니다.

localedir이 생략되거나 None이면, domain에 대한 현재 바인딩이 반환됩니다. 1

gettext.bind_textdomain_codeset(domain, codeset=None)

domaincodeset에 바인드하여, lgettext(), ldgettext(), lngettext()ldngettext() 함수에 의해 반환되는 바이트 문자열의 인코딩을 변경합니다. codeset이 생략되면, 현재 바인딩이 반환됩니다.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

gettext.textdomain(domain=None)

현재 전역 도메인을 변경하거나 조회합니다. domainNone이면, 현재 전역 도메인이 반환되고, 그렇지 않으면 전역 도메인이 domain으로 설정되어 반환됩니다.

gettext.gettext(message)

현재 전역 도메인, 언어 및 로케일 디렉터리를 기반으로, message의 현지화 된 번역을 반환합니다. 이 함수는 일반적으로 지역 이름 공간에서 _()로 별칭이 지정됩니다 (아래 예를 참조하십시오).

gettext.dgettext(domain, message)

gettext()와 비슷하지만, 지정된 domain에서 메시지를 찾습니다.

gettext.ngettext(singular, plural, n)

gettext()와 비슷하지만, 복수형(plural forms)을 고려합니다. 번역이 발견되면, 복수 공식을 n에 적용하고, 결과 메시지를 반환합니다 (일부 언어는 복수형이 두 개 이상입니다). 번역이 없으면, n이 1이면 singular를 반환합니다; 그렇지 않으면 plural을 반환합니다.

복수 공식은 카탈로그 헤더에서 취합니다. 자유 변수 n을 갖는 C나 파이썬 표현식입니다. 이 표현식은 카탈로그에서 복수의 인덱스로 평가됩니다. .po 파일에 사용되는 정확한 문법과 다양한 언어의 공식은 GNU gettext 설명서를 참조하십시오.

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

ngettext()와 비슷하지만, 지정된 domain에서 메시지를 찾습니다.

gettext.pgettext(context, message)
gettext.dpgettext(domain, context, message)
gettext.npgettext(context, singular, plural, n)
gettext.dnpgettext(domain, context, singular, plural, n)

접두사에 p가 없는 해당 함수(즉, gettext(), dgettext(), ngettext(), dngettext())와 유사하지만, 번역은 지정된 메시지 context로 제한됩니다.

버전 3.8에 추가.

gettext.lgettext(message)
gettext.ldgettext(domain, message)
gettext.lngettext(singular, plural, n)
gettext.ldngettext(domain, singular, plural, n)

l 접두어가 없는 해당 함수(gettext(), dgettext(), ngettext()dngettext())와 동등하지만, bind_textdomain_codeset()으로 명시적으로 설정된 다른 인코딩이 없으면 선호하는 시스템 인코딩으로 인코딩된 바이트 문자열로 번역이 반환됩니다.

경고

이 함수는 인코딩된 바이트열을 반환해서, 파이썬 3에서는 피해야 합니다. 대부분의 파이썬 응용 프로그램은 사람이 읽을 수 있는 텍스트를 바이트열 대신 문자열로 조작하기를 원하기 때문에, 유니코드 문자열을 반환하는 대안을 사용하는 것이 훨씬 좋습니다. 또한, 번역된 문자열에 인코딩 문제가 있으면 예기치 않은 유니코드 관련 예외가 발생할 수 있습니다.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

GNU gettextdcgettext() 메서드도 정의하지만, 이것을 유용하지 않은 것으로 간주해서 현재 구현되지 않았음에 유의하십시오.

이 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을 취합니다. 선택적 localedirbindtextdomain()에서와 같습니다. 선택적 languages는 문자열 리스트이며, 각 문자열은 언어 코드입니다.

localedir이 제공되지 않으면, 기본 시스템 로케일 디렉터리가 사용됩니다. 2 languages가 제공되지 않으면, 다음과 같은 환경 변수가 검색됩니다: LANGUAGE, LC_ALL, LC_MESSAGESLANG. 비어 있지 않은 값을 반환하는 첫 번째 것이 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, localedirlanguages를 기반으로 하는 *Translations 인스턴스를 반환합니다. 이 인스턴스는 연관된 .mo 파일 경로 리스트를 얻기 위해 먼저 find()로 전달됩니다. 동일한 .mo 파일 이름을 갖는 인스턴스는 캐시 됩니다. 인스턴스화되는 실제 클래스는 제공된다면 class_이고, 그렇지 않으면 GNUTranslations입니다. 클래스의 생성자는 단일 파일 객체 인자를 취해야 합니다. 제공되면, codesetlgettext()lngettext() 메서드에서 번역된 문자열을 인코딩하는 데 사용되는 문자 집합을 변경합니다.

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

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

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

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다.: codeset 매개 변수.

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

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

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

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

print(_('This string will be translated.'))

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

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다.: codeset 매개 변수.

NullTranslations 클래스

번역 클래스는 원본 소스 파일 메시지 문자열을 번역된 메시지 문자열로 실제로 구현합니다. 모든 번역 클래스에서 사용하는 베이스 클래스는 NullTranslations입니다; 여러분 자신의 특수화된 번역 클래스를 작성하는 데 사용할 수 있는 기본 인터페이스를 제공합니다. NullTranslations의 메서드는 다음과 같습니다:

class gettext.NullTranslations(fp=None)

베이스 클래스에서 무시되는, 선택적인 파일 객체 fp를 취합니다. 파생 클래스에 의해 설정되는 “보호되는” 인스턴스 변수 _info_charset 뿐만 아니라 add_fallback()을 통해 설정되는 _fallback을 초기화합니다. 그런 다음 fpNone이 아니면 self._parse(fp)를 호출합니다.

_parse(fp)

베이스 클래스에서 아무런 일도 하지 않는 이 메서드는 파일 객체 fp를 취하고, 이 파일에서 데이터를 읽고, 메시지 카탈로그를 초기화합니다. 지원되지 않는 메시지 카탈로그 파일 형식이 있으면, 이 메서드를 재정의하여 형식을 구문 분석해야 합니다.

add_fallback(fallback)

현재 번역 객체의 폴 백 객체로 fallback을 추가합니다. 주어진 메시지에 대한 번역을 제공할 수 없으면 번역 개체는 폴 백을 참조해야 합니다.

gettext(message)

폴 백이 설정되었으면, gettext()를 폴 백으로 전달합니다. 그렇지 않으면, message를 반환합니다. 파생 클래스에서 재정의됩니다.

ngettext(singular, plural, n)

폴 백이 설정되었으면, ngettext()를 폴 백으로 전달합니다. 그렇지 않으면, n이 1이면 singular를 반환합니다; 그렇지 않으면 plural을 반환합니다. 파생 클래스에서 재정의됩니다.

pgettext(context, message)

폴 백이 설정되었으면, pgettext()를 폴 백으로 전달합니다. 그렇지 않으면, 번역된 메시지를 반환합니다. 파생 클래스에서 재정의됩니다.

버전 3.8에 추가.

npgettext(context, singular, plural, n)

폴 백이 설정되었으면, npgettext()를 폴 백으로 전달합니다. 그렇지 않으면, 번역된 메시지를 반환합니다. 파생 클래스에서 재정의됩니다.

버전 3.8에 추가.

lgettext(message)
lngettext(singular, plural, n)

gettext()ngettext()와 동등하지만, set_output_charset()으로 인코딩을 명시적으로 설정하지 않았으면 선호하는 시스템 인코딩으로 인코딩된 바이트 문자열로 번역이 반환됩니다. 파생 클래스에서 재정의됩니다.

경고

이 메서드들은 파이썬 3에서 피해야 합니다. lgettext() 함수에 대한 경고를 참조하십시오.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

info()

메시지 카탈로그 파일에서 발견된 메타 데이터를 포함하는 딕셔너리인, “보호된” _info 변수를 반환합니다.

charset()

메시지 카탈로그 파일의 인코딩을 반환합니다.

output_charset()

lgettext()lngettext()에서 번역된 메시지를 반환하는 데 사용되는 인코딩을 반환합니다.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

set_output_charset(charset)

번역된 메시지를 반환하는 데 사용되는 인코딩을 변경합니다.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

install(names=None)

이 메서드는 gettext()를 내장 이름 공간에 설치하여, _에 연결합니다.

names 매개 변수가 제공되면, _()에 더해서 내장 이름 공간에 설치하려는 함수 이름이 포함된 시퀀스여야 합니다. 지원되는 이름은 'gettext', 'ngettext', 'pgettext', 'npgettext', 'lgettext''lngettext' 입니다.

이것은 _() 함수를 응용 프로그램에서 사용할 수 있게 하는 가장 편리한 방법이지만, 한 가지 방법일 뿐입니다. 전체 응용 프로그램, 특히 내장 이름 공간에 영향을 주기 때문에, 현지화된 모듈은 절대 _()를 설치하지 않아야 합니다. 대신, 다음과 같은 코드를 사용하여 _()를 모듈에서 사용할 수 있게 해야 합니다:

import gettext
t = gettext.translation('mymodule', ...)
_ = t.gettext

이는 _()를 모듈의 전역 이름 공간에만 넣기 때문에 이 모듈 내에서의 호출에만 영향을 줍니다.

버전 3.8에서 변경: 'pgettext''npgettext'를 추가했습니다.

GNUTranslations 클래스

gettext 모듈은 NullTranslations에서 파생된 클래스를 하나 더 제공합니다: GNUTranslations. 이 클래스는 _parse()를 재정의하여 빅 엔디안과 리틀 엔디안 형식의 GNU gettext 형식 .mo 파일을 읽을 수 있도록 합니다.

GNUTranslations는 번역 카탈로그에서 선택적 메타 데이터를 구문 분석합니다. 빈 문자열의 번역으로 메타 데이터를 포함하는 것이 GNU gettext의 관례입니다. 이 메타 데이터는 RFC 822 스타일 key: value 쌍이며, Project-Id-Version 키를 포함해야 합니다. 키 Content-Type이 발견되면, charset 프로퍼티를 사용하여 “보호된” _charset 인스턴스 변수를 초기화하고, 찾을 수 없으면 기본값은 None입니다. 문자 집합 인코딩이 지정되면, 카탈로그에서 읽은 모든 메시지 id와 메시지 문자열이 이 인코딩을 사용하여 유니코드로 변환되고, 그렇지 않으면 ASCII로 가정합니다.

메시지 id도 유니코드 문자열로 읽기 때문에, 모든 *gettext() 메서드는 메시지 id를 바이트 문자열이 아닌 유니코드 문자열로 가정합니다.

키/값 쌍의 전체 집합이 딕셔너리에 배치되고 “보호된” _info 인스턴스 변수로 설정됩니다.

.mo 파일의 매직 번호가 유효하지 않거나, 주 버전 번호가 예상치 못한 값이거나, 파일을 읽는 동안 다른 문제가 발생하면 GNUTranslations 클래스를 인스턴스 화할 때 OSError가 발생할 수 있습니다.

class gettext.GNUTranslations

베이스 클래스 구현에서 다음 메서드가 재정의되었습니다:

gettext(message)

카탈로그에서 message id를 찾아 해당 메시지 문자열을 유니코드 문자열로 반환합니다. 카탈로그에 message id에 대한 항목이 없고, 폴 백이 설정되었으면, 조회는 폴 백의 gettext() 메서드로 전달됩니다. 그렇지 않으면, message id가 반환됩니다.

ngettext(singular, plural, n)

메시지 id의 복수형 조회를 수행합니다. singular는 카탈로그에서 찾기 위해 메시지 id로 사용되는 반면, n은 사용할 복수형을 결정하는 데 사용됩니다. 반환된 메시지 문자열은 유니코드 문자열입니다.

카탈로그에서 메시지 id를 찾을 수 없고, 폴 백이 지정되었으면, 요청은 폴 백의 ngettext() 메서드로 전달됩니다. 그렇지 않으면, n이 1이면 singular가 반환되고, 다른 모든 경우에는 plural이 반환됩니다.

예를 들면 다음과 같습니다:

n = len(os.listdir('.'))
cat = GNUTranslations(somefile)
message = cat.ngettext(
    'There is %(num)d file in this directory',
    'There are %(num)d files in this directory',
    n) % {'num': n}
pgettext(context, message)

카탈로그에서 contextmessage id를 찾아 해당 메시지 문자열을 유니코드 문자열로 반환합니다. 카탈로그에 message id와 context에 대한 항목이 없고, 폴 백이 설정되었으면, 조회는 폴 백의 pgettext() 메서드로 전달됩니다. 그렇지 않으면, message id가 반환됩니다.

버전 3.8에 추가.

npgettext(context, singular, plural, n)

메시지 ID의 복수형 조회를 수행합니다. singular는 카탈로그에서 찾기 위해 메시지 id로 사용되는 반면, n은 사용할 복수형을 결정하는 데 사용됩니다.

context의 메시지 id가 카탈로그에 없고, 폴 백이 지정되었으면, 요청은 폴 백의 npgettext() 메서드로 전달됩니다. 그렇지 않으면, n이 1이면 singular가 반환되고, 다른 모든 경우에는 plural이 반환됩니다.

버전 3.8에 추가.

lgettext(message)
lngettext(singular, plural, n)

gettext()ngettext()와 동등하지만, set_output_charset()으로 인코딩이 명시적으로 설정되지 않았으면 선호하는 시스템 인코딩으로 인코딩된 바이트 문자열로 번역이 반환됩니다.

경고

이 메서드들은 파이썬 3에서 피해야 합니다. lgettext() 함수에 대한 경고를 참조하십시오.

버전 3.8에서 폐지되었습니다, 버전 3.10에서 제거되었습니다..

Solaris 메시지 카탈로그 지원

Solaris 운영 체제는 자체 바이너리 .mo 파일 형식을 정의하지만, 이 형식에 대한 설명서를 찾을 수 없어서, 현재 지원되지 않습니다.

Catalog 생성자

GNOME은 James Henstridge의 gettext 모듈 버전을 사용하지만, 이 버전은 API가 약간 다릅니다. 설명된 사용법은 다음과 같습니다:

import gettext
cat = gettext.Catalog(domain, localedir)
_ = cat.gettext
print(_('hello world'))

이 이전 모듈과의 호환성을 위해, 함수 Catalog()는 위에서 설명한 translation() 함수의 별칭입니다.

이 모듈과 Henstridge 버전의 한 가지 차이점: 그의 카탈로그 객체는 매핑 API를 통한 액세스를 지원했지만, 사용되지 않는 것으로 보여서 현재 지원되지 않습니다.

프로그램과 모듈의 국제화

국제화(I18N)는 프로그램이 여러 언어를 인식하도록 하는 작업을 말합니다. 현지화(L10N)는 일단 국제화된 프로그램이 현지 언어와 문화적 습관에 적응하는 것을 말합니다. 파이썬 프로그램에 다국어 메시지를 제공하려면, 다음 단계를 수행해야 합니다:

  1. 번역 가능한 문자열을 특별히 표시하여 프로그램이나 모듈을 준비합니다

  2. 표시된 파일에 대해 도구 모음을 실행하여 원시 메시지 카탈로그를 생성합니다

  3. 메시지 카탈로그의 언어별 번역을 만듭니다

  4. 메시지 문자열이 올바르게 번역되도록 gettext 모듈을 사용합니다

I18N을 위해 여러분의 코드를 준비하려면, 파일의 모든 문자열을 확인해야 합니다. 번역해야 할 모든 문자열은 _('...')로 감싸서 표시해야 합니다 — 즉, 함수 _()에 대한 호출. 예를 들면:

filename = 'mylog.txt'
message = _('writing a log message')
with open(filename, 'w') as fp:
    fp.write(message)

이 예에서, 문자열 'writing a log message'는 번역 후보로 표시되지만, 문자열 'mylog.txt''w'는 그렇지 않습니다.

There are a few tools to extract the strings meant for translation. The original GNU gettext only supported C or C++ source code but its extended version xgettext scans code written in a number of languages, including Python, to find strings marked as translatable. Babel is a Python internationalization library that includes a pybabel script to extract and compile message catalogs. François Pinard’s program called xpot does a similar job and is available as part of his po-utils package.

(파이썬에는 pygettext.pymsgfmt.py라고 하는 이러한 프로그램의 순수 파이썬 버전도 포함되어 있습니다; 일부 파이썬 배포판은 이 프로그램들을 설치합니다. pygettext.pyxgettext와 유사하지만, 파이썬 소스 코드만 이해하며 C나 C++ 와 같은 다른 프로그래밍 언어를 처리할 수 없습니다. pygettext.pyxgettext와 유사한 명령 줄 인터페이스를 지원합니다; 사용에 대한 자세한 내용을 보려면, pygettext.py --help를 실행하십시오. msgfmt.py는 GNU msgfmt와 바이너리 호환됩니다. 이 두 프로그램을 사용하면, 파이썬 응용 프로그램을 국제화하기 위해 GNU gettext 패키지가 필요하지 않을 수 있습니다.)

xgettext, pygettext 및 유사한 도구는 메시지 카탈로그인 .po 파일을 생성합니다. 이 파일은 소스 코드에 표시된 모든 문자열과 이러한 문자열의 번역된 버전에 대한 자리를 포함하는 사람이 읽을 수 있는 파일입니다.

.po 파일의 사본은 지원되는 모든 자연어에 대한 번역을 작성하는 개별 인간 번역가에게 전달됩니다. 완성된 언어별 버전을 <language-name>.po 파일로 다시 보내고, 이는 msgfmt 프로그램을 사용하여 기계가 읽을 수 있는 .mo 바이너리 카탈로그 파일로 컴파일됩니다. .mo 파일은 실행 시간에 실제 번역 처리를 위해 gettext 모듈에서 사용됩니다.

코드에서 gettext 모듈을 사용하는 방법은 단일 모듈을 국제화하는지 또는 전체 응용 프로그램을 국제화하는지에 따라 다릅니다. 다음 두 섹션에서는 각 사례에 관해 설명합니다.

모듈 현지화

모듈을 현지화한다면, 전역적인 변경을 가하지 않도록 주의해야 합니다, 예를 들어, 내장 이름 공간. GNU gettext API 대신 클래스 기반 API를 사용해야 합니다.

모듈이 “spam”이고 모듈의 다양한 자연어 번역 .mo 파일이 /usr/share/locale에 GNU gettext 형식으로 존재한다고 가정해 봅시다. 다음은 모듈 맨 위에 들어갈 내용입니다:

import gettext
t = gettext.translation('spam', '/usr/share/locale')
_ = t.gettext

응용 프로그램 현지화

응용 프로그램을 현지화한다면, _() 함수를 전역적으로 내장 이름 공간에 설치할 수 있습니다, 일반적으로 응용 프로그램의 메인 드라이버 파일에서. 이렇게 하면 모든 응용 프로그램별 파일이 각 파일에 명시적으로 설치하지 않고도 _('...')를 사용할 수 있습니다.

간단한 경우에는, 응용 프로그램의 메인 드라이버 파일에 다음 코드만 추가하면 됩니다:

import gettext
gettext.install('myapplication')

로케일 디렉터리를 설정해야 하면, install() 함수로 전달할 수 있습니다:

import gettext
gettext.install('myapplication', '/usr/share/locale')

실행 중 언어 변경

프로그램에서 동시에 여러 언어를 지원해야 하면, 다음과 같은 식으로 여러 번역 인스턴스를 만든 다음 명시적으로 전환할 수 있습니다:

import gettext

lang1 = gettext.translation('myapplication', languages=['en'])
lang2 = gettext.translation('myapplication', languages=['fr'])
lang3 = gettext.translation('myapplication', languages=['de'])

# start by using language1
lang1.install()

# ... time goes by, user selects language 2
lang2.install()

# ... more time goes by, user selects language 3
lang3.install()

지연된 번역

대부분의 코딩 상황에서, 문자열은 코딩된 위치에서 번역됩니다. 그러나 때때로, 번역을 위해 문자열을 표시하지만, 실제 번역을 뒤로 연기할 필요가 있습니다. 전형적인 예는 다음과 같습니다:

animals = ['mollusk',
           'albatross',
           'rat',
           'penguin',
           'python', ]
# ...
for a in animals:
    print(a)

여기서, animals 리스트의 문자열을 번역 가능한 것으로 표시하려고 하지만, 실제로 인쇄될 때까지 번역하고 싶지는 않습니다.

이 상황을 처리 할 수 있는 한 가지 방법은 다음과 같습니다:

def _(message): return message

animals = [_('mollusk'),
           _('albatross'),
           _('rat'),
           _('penguin'),
           _('python'), ]

del _

# ...
for a in animals:
    print(_(a))

이것이 작동하는 이유는 _()의 더미 정의가 단순히 문자열을 변경하지 않고 반환하기 때문입니다. 그리고 이 더미 정의는 내장 이름 공간에서 _()의 정의를 일시적으로 재정의합니다 (del 명령까지). 지역 이름 공간에 _()의 이전 정의가 있다면 주의하십시오.

_()의 두 번째 사용은 매개 변수가 문자열 리터럴이 아니기 때문에 gettext 프로그램이 “a”를 번역 가능하다고 식별하지 않음에 유의하십시오.

이를 처리하는 다른 방법은 다음 예제를 사용하는 것입니다:

def N_(message): return message

animals = [N_('mollusk'),
           N_('albatross'),
           N_('rat'),
           N_('penguin'),
           N_('python'), ]

# ...
for a in animals:
    print(_(a))

이 경우, 번역 가능한 문자열을 N_() 함수로 표시하는데, _()의 정의와 충돌하지 않습니다. 그러나, N_()로 표시된 번역 가능한 문자열을 찾도록 메시지 추출 프로그램을 가르쳐야 할 필요가 있습니다. xgettext, pygettext, pybabel extractxpot은 모두 -k 명령 줄 스위치를 사용하여 이를 지원합니다. 여기서 N_()의 선택은 완전히 임의적입니다; MarkThisStringForTranslation()처럼 무엇이든 될 수 있습니다.

감사의 말

다음 분들은 이 모듈을 만드는 데 코드, 피드백, 디자인 제안, 이전 구현 및 귀중한 경험을 제공했습니다:

  • Peter Funk

  • James Henstridge

  • Juan David Ibáñez Palomar

  • Marc-André Lemburg

  • Martin von Löwis

  • François Pinard

  • Barry Warsaw

  • Gustavo Niemeyer

각주

1

기본 로케일 디렉터리는 시스템에 따라 다릅니다; 예를 들어 RedHat 리눅스에서는 /usr/share/locale이지만, Solaris에서는 /usr/lib/locale입니다. gettext 모듈은 이러한 시스템 종속 기본값을 지원하려고 하지 않습니다; 대신 기본값은 sys.base_prefix/share/locale입니다 (sys.base_prefix를 참조하십시오). 이런 이유로, 항상 응용 프로그램 시작 시 명시적 절대 경로를 사용하여 bindtextdomain()을 호출하는 것이 가장 좋습니다.

2

위의 bindtextdomain()에 대한 각주를 참조하십시오.