# 23.2. `locale` --- 国際化サービス

ソースコード: Lib/locale.py

`locale` モジュールは POSIX ロケールデータベースおよびロケール関連機能へのアクセスを提供します。 POSIX ロケール機構を使うことで、プログラマはソフトウェアが実行される各国における詳細を知らなくても、アプリケーション上で特定の地域文化に関係する部分を扱うことができます。

`locale` モジュールは、 `_locale` を被うように実装されており、ANSI C ロケール実装を使っている `_locale` が利用可能なら、こちらを先に使うようになっています。

`locale` モジュールでは以下の例外と関数を定義しています:

exception `locale.``Error`

  `setlocale()` に渡されたロケールが認識されない場合例外が送出されます。

`locale.``setlocale`(category, locale=None)

  locale が渡され `None` でない場合、`setlocale()` は category のロケール設定を変更します。利用可能なカテゴリーは下記の表を参照してください。 locale は文字列か2つの文字列の iterable (言語コードと文字コード) です。iterale の場合 locale aliasing engine を用いてロケール名に変換されます。空の文字列はユーザのデフォルトの設定を指定します。ロケールの変更に失敗した場合 `Error` が送出されます。成功した場合新しいロケールの設定が返されます。

  locale が省略されたり `None` の場合、category の現在の設定が返されます。

  `setlocale()` はほとんどのシステムでスレッド安全ではありません。アプリケーションを書くとき、大抵は以下のコード

      import locale
      locale.setlocale(locale.LC_ALL, '')

  から書き始めます。これは全てのカテゴリをユーザの環境における標準設定 (大抵は環境変数 `LANG` で指定されています) に設定します。その後複数スレッドを使ってロケールを変更したりしない限り、問題は起こらないはずです。

`locale.``localeconv`()

  地域的な慣行のデータベースを辞書として返します。辞書は以下の文字列をキーとして持っています:

  カテゴリ | キー | 意味
  --- | --- | ---
  `LC_NUMERIC` | `'decimal_point'` | 小数点を表す文字です。
  | `'grouping'` | `'thousands_sep'` が来るかもしれない場所を相対的に表した数からなる配列です。配列が `CHAR_MAX` で終端されている場合、それ以上の桁では桁数字のグループ化を行いません。配列が `0` で終端されている場合、最後に指定したグループが反復的に使われます。
  | `'thousands_sep'` | 桁グループ間を区切るために使われる文字です。
  `LC_MONETARY` | `'int_curr_symbol'` | 国際通貨を表現する記号です。
  | `'currency_symbol'` | 地域的な通貨を表現する記号です。
  | `'p_cs_precedes/n_cs_precedes'` | 通貨記号が値の前につくかどうかです (それぞれ正の値、負の値を表します)。
  | `'p_sep_by_space/n_sep_by_space'` | 通貨記号と値との間にスペースを入れるかどうかです (それぞれ正の値、負の値を表します)。
  | `'mon_decimal_point'` | 金額表示の際に使われる小数点です。
  | `'frac_digits'` | 金額を地域的な方法で表現する際の小数点以下の桁数です。
  | `'int_frac_digits'` | 金額を国際的な方法で表現する際の小数点以下の桁数です。
  | `'mon_thousands_sep'` | 金額表示の際に桁区切り記号です。
  | `'mon_grouping'` | `'grouping'` と同じで、金額表示の際に使われます。
  | `'positive_sign'` | 正の値の金額表示に使われる記号です。
  | `'negative_sign'` | 負の値の金額表示に使われる記号です。
  | `'p_sign_posn/n_sign_posn'` | 符号の位置です (それぞれ正の値と負の値を表します)。以下を参照してください。

  数値形式の値に `CHAR_MAX` を設定すると、そのロケールでは値が指定されていないことを表します。

  `'p_sign_posn'` および `'n_sign_posn'` の取り得る値は以下の通りです。

  値 | 説明
  --- | ---
  `0` | 通貨記号および値は丸括弧で囲われます。
  `1` | 符号は値と通貨記号より前に来ます。
  `2` | 符号は値と通貨記号の後に続きます。
  `3` | 符号は値の直前に来ます。
  `4` | 符号は値の直後に来ます。
  `CHAR_MAX` | このロケールでは特に指定しません。

  `LC_NUMERIC` ロケールや `LC_MONETARY` ロケールが `LC_CTYPE` ロケールと異なっていて、数値文字列や通貨文字列が非 ASCII 文字列の場合、この関数は一時的に `LC_NUMERIC` ロケールや `LC_MONETARY` ロケールに `LC_CTYPE` ロケールを設定します。 この一時的な変更は他のスレッドに影響を及ぼします。

  バージョン 3.6.5 で変更: この関数は、一時的に `LC_NUMERIC` ロケールに `LC_CTYPE` ロケールを設定する場合があります。

`locale.``nl_langinfo`(option)

  ロケール特有の情報を文字列として返します。この関数は全てのシステムで利用可能なわけではなく、指定できる option もプラットフォーム間で大きく異なります。引数として使えるのは、locale モジュールで利用可能なシンボル定数を表す数字です。

  関数 `nl_langinfo()` は以下のキーのうち一つを受理します。ほとんどの記述は GNU C ライブラリ中の対応する説明から引用されています。

  `locale.``CODESET`

    選択されたロケールで用いられている文字エンコーディングの名前を文字列で取得します。

  `locale.``D_T_FMT`

    日付と時刻をロケール特有の方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``D_FMT`

    日付をロケール特有の方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``T_FMT`

    時刻をロケール特有の方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``T_FMT_AMPM`

    時刻を午前／午後の書式で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `DAY_1 ... DAY_7`

    1 週間中の n 番目の曜日名を取得します。

    注釈

    ロケール US における、 `DAY_1` を日曜日とする慣行に従っています。国際的な (ISO 8601) 月曜日を週の初めとする慣行ではありません。

  `ABDAY_1 ... ABDAY_7`

    1 週間中の n 番目の曜日名を略式表記で取得します。

  `MON_1 ... MON_12`

    n 番目の月の名前を取得します。

  `ABMON_1 ... ABMON_12`

    n 番目の月の名前を略式表記で取得します。

  `locale.``RADIXCHAR`

    基数点 (小数点ドット、あるいは小数点コンマ、等) を取得します。

  `locale.``THOUSEP`

    1000 単位桁区切り (3 桁ごとのグループ化) の区切り文字を取得します。

  `locale.``YESEXPR`

    肯定／否定で答える質問に対する肯定回答を正規表現関数で認識するために利用できる正規表現を取得します。

    注釈

    表現は C ライブラリの `regex()` 関数に合ったものでなければならず、これは `re` で使われている構文とは異なるかもしれません。

  `locale.``NOEXPR`

    肯定／否定で答える質問に対する否定回答を正規表現関数で認識するために利用できる正規表現を取得します。

  `locale.``CRNCYSTR`

    通貨シンボルを取得します。シンボルを値の前に表示させる場合には "-"、値の後ろに表示させる場合には "+"、シンボルを基数点と置き換える場合には "." を前につけます。

  `locale.``ERA`

    現在のロケールで使われている年代を表現する値を取得します。

    ほとんどのロケールではこの値を定義していません。この値を設定しているロケールの例は Japanese です。日本には日付の伝統的な表示法として、時の天皇に対応する元号名があります。

    通常この値を直接指定する必要はありません。 `E` を書式文字列に指定することで、関数 `time.strftime()` がこの情報を使うようになります。返される文字列の様式は決められていないので、異なるシステム間で様式に関する同じ知識が使えると期待してはいけません。

  `locale.``ERA_D_T_FMT`

    日付および時間をロケール固有の年代に基づいた方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``ERA_D_FMT`

    日付をロケール固有の年代に基づいた方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``ERA_T_FMT`

    時刻をロケール固有の年代に基づいた方法で表現するために、 `time.strftime()` の書式文字列として用いることのできる文字列を取得します。

  `locale.``ALT_DIGITS`

    返される値は 0 から 99 までの 100 個の値の表現です。

`locale.``getdefaultlocale`([envvars])

  標準のロケール設定を取得しようと試み、結果をタプル `(language code, encoding)` の形式で返します。

  POSIXによると、 `setlocale(LC_ALL, '')` を呼ばなかったプログラムは、移植可能な `'C'` ロケール設定を使います。 `setlocale(LC_ALL, '')` を呼ぶことで、 `LANG` 変数で定義された標準のロケール設定を使うようになります。 Python では現在のロケール設定に干渉したくないので、上で述べたような方法でその挙動をエミュレーションしています。

  他のプラットフォームとの互換性を維持するために、環境変数 `LANG` だけでなく、引数 envvars で指定された環境変数のリストも調べられます。最初に見つかった定義が使われます。 envvars は標準では GNU gettext で使われている検索順になります; これは常に変数名 `LANG` を探します。GNU gettext では `'LC_ALL'` 、 `'LC_CTYPE'` 、 `'LANG'` 、および `'LANGUAGE'` の順に調べられます。

  `'C'` の場合を除き、言語コードは RFC 1766 に対応します。 language code および encoding が決定できなかった場合、 `None` になるかもしれません。

`locale.``getlocale`(category=LC_CTYPE)

  与えられたロケールカテゴリに対する現在の設定を、 language code 、 encoding を含むシーケンスで返します。 category として `LC_ALL` 以外の `LC_*` の値の一つを指定できます。標準の設定は `LC_CTYPE` です。

  `'C'` の場合を除き、言語コードは RFC 1766 に対応します。 language code および encoding が決定できなかった場合、 `None` になるかもしれません。

`locale.``getpreferredencoding`(do_setlocale=True)

  テキストデータをエンコードする方法を、ユーザの設定に基づいて返します。ユーザの設定は異なるシステム間では異なった方法で表現され、システムによってはプログラミング的に得ることができないこともあるので、この関数が返すのはただの推測です。

  システムによっては、ユーザの設定を取得するために `setlocale()` を呼び出す必要があるため、この関数はスレッド安全ではありません。 `setlocale()` を呼び出す必要がない、または呼び出したくない場合、 do_setlocale を `False` に設定する必要があります。

`locale.``normalize`(localename)

  与えたロケール名を規格化したロケールコードを返します。返されるロケールコードは `setlocale()` で使うために書式化されています。規格化が失敗した場合、もとの名前がそのまま返されます。

  与えたエンコードがシステムにとって未知の場合、標準の設定では、この関数は `setlocale()` と同様に、エンコーディングをロケールコードにおける標準のエンコーディングに設定します。

`locale.``resetlocale`(category=LC_ALL)

  category のロケールを標準設定にします。

  標準設定は `getdefaultlocale()` を呼ぶことで決定されます。 category は標準で `LC_ALL` になっています。

`locale.``strcoll`(string1, string2)

  現在の `LC_COLLATE` 設定に従って二つの文字列を比較します。他の比較を行う関数と同じように、 string1 が string2 に対して前に来るか、後に来るか、あるいは二つが等しいかによって、それぞれ負の値、正の値、あるいは `0` を返します。

`locale.``strxfrm`(string)

  文字列を、ロケールを考慮した比較に使える形式に変換します。例えば、 `strxfrm(s1) < strxfrm(s2)` は `strcoll(s1, s2) < 0` と等価です。この関数は同じ文字列が何度も比較される場合、例えば文字列からなるシーケンスを順序付けて並べる際に使うことができます。

`locale.``format`(format, val, grouping=False, monetary=False)

  数値 val を現在の `LC_NUMERIC` の設定に基づいて書式化します。書式は `%` 演算子の慣行に従います。浮動小数点数については、必要に応じて浮動小数点が変更されます。 grouping が真なら、ロケールに配慮した桁数の区切りが行われます。

  monetary が真なら、桁区切り記号やグループ化文字列を用いて変換を行います。

  この関数や、1文字の指定子でしか動作しないことに注意しましょう。フォーマット文字列を使う場合は `format_string()` を使用します。

`locale.``format_string`(format, val, grouping=False)

  `format % val` 形式のフォーマット指定子を、現在のロケール設定を考慮したうえで処理します。

`locale.``currency`(val, symbol=True, grouping=False, international=False)

  数値 val を、現在の `LC_MONETARY` の設定にあわせてフォーマットします。

  symbol が真の場合は、返される文字列に通貨記号が含まれるようになります。これはデフォルトの設定です。grouping が真の場合(これはデフォルトではありません)は、値をグループ化します。international が真の場合(これはデフォルトではありません)は、国際的な通貨記号を使用します。

  この関数は'C'ロケールでは動作しないことに注意しましょう。まず最初に `setlocale()` でロケールを設定する必要があります。

`locale.``str`(float)

  浮動小数点数を `str(float)` と同じように書式化しますが、ロケールに配慮した小数点が使われます。

`locale.``delocalize`(string)

  文字列を `LC_NUMERIC` で設定された慣行に従って正規化された数値文字列に変換します。

  バージョン 3.5 で追加.

`locale.``atof`(string)

  文字列を `LC_NUMERIC` で設定された慣行に従って浮動小数点に変換します。

`locale.``atoi`(string)

  文字列を `LC_NUMERIC` で設定された慣行に従って整数に変換します。

`locale.``LC_CTYPE`

  文字タイプ関連の関数のためのロケールカテゴリです。このカテゴリの設定に従って、モジュール `string` における関数の振る舞いが変わります。

`locale.``LC_COLLATE`

  文字列を並べ替えるためのロケールカテゴリです。 `locale` モジュールの関数 `strcoll()` および `strxfrm()` が影響を受けます。

`locale.``LC_TIME`

  時刻を書式化するためのロケールカテゴリです。 `time.strftime()` はこのカテゴリに設定されている慣行に従います。

`locale.``LC_MONETARY`

  金額に関係する値を書式化するためのロケールカテゴリです。設定可能なオプションは関数 `localeconv()` で得ることができます。

`locale.``LC_MESSAGES`

  メッセージ表示のためのロケールカテゴリです。現在 Python はアプリケーション毎にロケールに対応したメッセージを出力する機能はサポートしていません。 `os.strerror()` が返すような、オペレーティングシステムによって表示されるメッセージはこのカテゴリによって影響を受けます。

`locale.``LC_NUMERIC`

  数字を書式化するためのロケールカテゴリです。関数 `format()` 、 `atoi()` 、 `atof()` および `locale` モジュールの `str()` が影響を受けます。他の数値書式化操作は影響を受けません。

`locale.``LC_ALL`

  全てのロケール設定を総合したものです。ロケールを変更する際にこのフラグが使われた場合、そのロケールにおける全てのカテゴリを設定しようと試みます。一つでも失敗したカテゴリがあった場合、全てのカテゴリにおいて設定変更を行いません。このフラグを使ってロケールを取得した場合、全てのカテゴリにおける設定を示す文字列が返されます。この文字列は、後に設定を元に戻すために使うことができます。

`locale.``CHAR_MAX`

  `localeconv()` の返す特別な値のためのシンボル定数です。

以下はプログラム例です:

    >>> import locale
    >>> loc = locale.getlocale()  # get current locale
    # use German locale; name might vary with platform
    >>> locale.setlocale(locale.LC_ALL, 'de_DE')
    >>> locale.strcoll('f\xe4n', 'foo')  # compare a string containing an umlaut
    >>> locale.setlocale(locale.LC_ALL, '')   # use user's preferred locale
    >>> locale.setlocale(locale.LC_ALL, 'C')  # use default (C) locale
    >>> locale.setlocale(locale.LC_ALL, loc)  # restore saved locale

## 23.2.1. ロケールの背景、詳細、ヒント、助言および補足説明

C 標準では、ロケールはプログラム全体にわたる特性であり、その変更は高価な処理であるとしています。加えて、頻繁にロケールを変更するようなひどい実装はコアダンプを引き起こすこともあります。このことがロケールを正しく利用する上で苦痛となっています。

最初、プログラムが起動したときには、ユーザの希望するロケールにかかわらずロケールは `C` です。例外が1つあります: `LC_CTYPE` カテゴリは、現在のロケールエンコーディングをユーザーの希望するロケールエンコーディングに設定するために、スタートアップで変更されます。他のカテゴリについては、プログラムは `setlocale(LC_ALL, '')` を呼び出して、明示的にユーザの希望するロケール設定を行わなければなりません。

`setlocale()` をライブラリルーチン内で呼ぶことは、それがプログラム全体に及ぼす副作用の面から、一般的によくない考えです。ロケールを保存したり復帰したりするのもよくありません: 高価な処理であり、ロケールの設定が復帰する以前に起動してしまった他のスレッドに悪影響を及ぼすからです。

もし、汎用を目的としたモジュールを作っていて、ロケールによって影響をうけるような操作 (例えば `time.strftime()` の書式の一部) のロケール独立のバージョンが必要ということになれば、標準ライブラリルーチンを使わずに何とかしなければなりません。よりましな方法は、ロケール設定が正しく利用できているか確かめることです。最後の手段は、あなたのモジュールが `C` ロケール以外の設定には互換性がないとドキュメントに書くことです。

ロケールに従って数値操作を行うための唯一の方法はこのモジュールで特別に定義されている関数: `atof()` 、 `atoi()` 、 `format()` 、 `str()` を使うことです。

ロケールに従ってケース変換や文字分類を行う方法はありません。 (ユニコード) テキスト文字列については、これらは文字の値のみによって行われます。その一方、バイト文字列はバイトの ASCII 値に従って変換と分類が行われます。そして、上位ビットが立っているバイト (すなわち、non-ASCII バイト) は、決して変換されず、英字や空白などの文字クラスの一部とみなされることもありません。

## 23.2.2. Python 拡張の作者と、Python を埋め込むようなプログラムに関して

拡張モジュールは、現在のロケールを調べる以外は、決して `setlocale()` を呼び出してはなりません。しかし、返される値もロケールの復帰のために使えるだけなので、さほど便利とはいえません (例外はおそらくロケールが `C` かどうか調べることでしょう)。

ロケールを変更するために Python コードで `locale` モジュールを使った場合、Python を埋め込んでいるアプリケーションにも影響を及ぼします。Python を埋め込んでいるアプリケーションに影響が及ぶことを望まない場合、 `config.c` ファイル内の組み込みモジュールのテーブルから `_locale` 拡張モジュール (ここで全てを行っています) を削除し、共有ライブラリから `_locale` モジュールにアクセスできないようにしてください。

## 23.2.3. メッセージカタログへのアクセス

`locale.``gettext`(msg)

`locale.``dgettext`(domain, msg)

`locale.``dcgettext`(domain, msg, category)

`locale.``textdomain`(domain)

`locale.``bindtextdomain`(domain, dir)

C ライブラリの gettext インタフェースが提供されているシステムでは、 locake モジュールでそのインタフェースを公開しています。このインタフェースは関数 `gettext()` 、 `dgettext()` 、 `dcgettext()` 、 `textdomain()` 、 `bindtextdomain()` 、 `bind_textdomain_codeset()` からなります。これらは `gettext` モジュールの同名の関数に似ていますが、メッセージカタログとして C ライブラリのバイナリフォーマットを使い、メッセージカタログを探すために C ライブラリの検索アルゴリズムを使います。

Python アプリケーションでは、通常これらの関数を呼び出す必要はないはずで、代わりに `gettext` を呼ぶべきです。例外として知られているのは、内部で `gettext()` または `dcgettext()` を呼び出すような C ライブラリにリンクするアプリケーションです。こうしたアプリケーションでは、ライブラリが正しいメッセージカタログを探せるようにテキストドメイン名を指定する必要があります。