"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_MESSAGES" 및
   "LANG"에서 각각 검색됩니다.

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

gettext.textdomain(domain=None)

   현재 전역 도메인을 변경하거나 조회합니다. *domain*이 "None"이면, 현
   재 전역 도메인이 반환되고, 그렇지 않으면 전역 도메인이 *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*로 제한됩니다.

   Added in version 3.8.

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

이 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)

   *domain*, *localedir* 및 *languages*를 기반으로 하는
   "*Translations" 인스턴스를 반환합니다. 이 인스턴스는 연관된 ".mo"
   파일 경로 리스트를 얻기 위해 먼저 "find()"로 전달됩니다. 동일한
   ".mo" 파일 이름을 갖는 인스턴스는 캐시 됩니다. 인스턴스화되는 실제
   클래스는 제공된다면 *class_*이고, 그렇지 않으면 "GNUTranslations"입
   니다. 클래스의 생성자는 단일 *파일 객체* 인자를 취해야 합니다.

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

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

   버전 3.3에서 변경: 이전에는 "IOError"가 발생했지만, 이제는
   "OSError"의 별칭입니다.

   버전 3.11에서 변경: *codeset* 매개 변수를 제거했습니다.

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

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

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

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

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

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

   버전 3.11에서 변경: *names*는 이제 키워드 전용 매개 변수입니다.


"NullTranslations" 클래스
-------------------------

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

class gettext.NullTranslations(fp=None)

   베이스 클래스에서 무시되는, 선택적인 *파일 객체* *fp*를 취합니다.
   파생 클래스에 의해 설정되는 "보호되는" 인스턴스 변수 *_info*와
   *_charset* 뿐만 아니라 "add_fallback()"을 통해 설정되는 *_fallback*
   을 초기화합니다. 그런 다음 *fp*가 "None"이 아니면 "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()"를 폴 백으로 전달합니다. 그렇
      지 않으면, 번역된 메시지를 반환합니다. 파생 클래스에서 재정의됩
      니다.

      Added in version 3.8.

   npgettext(context, singular, plural, n)

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

      Added in version 3.8.

   info()

      메시지 카탈로그 파일에서 발견된 메타 데이터를 포함하는 딕셔너리
      를 반환합니다.

   charset()

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

   install(names=None)

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

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

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

         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)

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

      Added in version 3.8.

   npgettext(context, singular, plural, n)

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

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

      Added in version 3.8.


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'"는 그렇지 않습니다.

번역을 위한 문자열을 추출하는 몇 가지 도구가 있습니다. 원래 GNU
**gettext**는 C나 C++ 소스 코드만 지원했지만, 확장 버전 **xgettext**는
파이썬을 포함하여 여러 언어로 작성된 코드를 스캔하여 번역 가능으로 표
시된 문자열을 찾습니다. Babel은 메시지 카탈로그를 추출하고 컴파일하는
"pybabel" 스크립트를 포함하는 파이썬 국제화 라이브러리입니다. **xpot**
이라는 François Pinard의 프로그램도 비슷한 작업을 수행하며 그의 po-
utils 패키지의 일부로 제공됩니다.

(파이썬에는 **pygettext.py**와 **msgfmt.py**라고 하는 이러한 프로그램
의 순수 파이썬 버전도 포함되어 있습니다; 일부 파이썬 배포판은 이 프로
그램들을 설치합니다. **pygettext.py**는 **xgettext**와 유사하지만, 파
이썬 소스 코드만 이해하며 C나 C++ 와 같은 다른 프로그래밍 언어를 처리
할 수 없습니다. **pygettext.py**는 **xgettext**와 유사한 명령 줄 인터
페이스를 지원합니다; 사용에 대한 자세한 내용을 보려면, "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'])

   # 언어 1을 사용하는 것으로 시작합니다
   lang1.install()

   # ... 시간이 지난 후에, 사용자가 언어 2를 선택합니다
   lang2.install()

   # ... 시간이 더 흐른 후에, 사용자가 언어 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 extract" 및 **xpot**은 모두 "-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] 기본 로케일 디렉터리는 시스템에 따라 다릅니다; 예를 들어 Red Hat
    리눅스에서는 "/usr/share/locale"이지만, Solaris에서는
    "/usr/lib/locale"입니다. "gettext" 모듈은 이러한 시스템 종속 기본
    값을 지원하려고 하지 않습니다; 대신 기본값은
    "*sys.base_prefix*/share/locale"입니다 ("sys.base_prefix"를 참조하
    십시오). 이런 이유로, 항상 응용 프로그램 시작 시 명시적 절대 경로
    를 사용하여 "bindtextdomain()"을 호출하는 것이 가장 좋습니다.

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