Автор оригинала: Doug Hellmann.
Цель:
Форматируйте и анализируйте значения, зависящие от местоположения или языка.
Модуль locale
является частью библиотеки поддержки интернационализации и локализации Python. Он предоставляет стандартный способ обработки операций, которые могут зависеть от языка или местонахождения пользователя. Например, он обрабатывает форматирование чисел как валют, сравнивает строки для сортировки и работает с датами. Он не распространяется на перевод (см. Модуль gettext) или кодировку Unicode (см. Модуль кодеков).
Примечание
Изменение языкового стандарта может иметь последствия для всего приложения, поэтому рекомендуется избегать изменения значения в библиотеке и позволить приложению установить его один раз. В примерах этого раздела языковой стандарт изменяется несколько раз в рамках короткой программы, чтобы подчеркнуть различия в настройках различных языковых стандартов. Гораздо более вероятно, что приложение установит языковой стандарт один раз при запуске или при получении веб-запроса и не изменит его.
В этом разделе рассматриваются некоторые высокоуровневые функции модуля locale
. Есть и другие, которые относятся к более низкому уровню или относятся к управлению локалью для приложения ( resetlocale ()
).
Проверка текущего языкового стандарта
Наиболее распространенный способ позволить пользователю изменить настройки локали для приложения – использовать переменную среды ( LC_ALL
, LC_CTYPE
, LANG
или < code> LANGUAGE , в зависимости от платформы). Затем приложение вызывает setlocale ()
без жестко запрограммированного значения, и используется значение среды.
locale_env.py
import locale import os import pprint # Default settings based on the user's environment. locale.setlocale(locale.LC_ALL, '') print('Environment settings:') for env_name in ['LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE']: print(' {} = {}'.format( env_name, os.environ.get(env_name, '')) ) # What is the locale? print('\nLocale from environment:', locale.getlocale()) template """ Numeric formatting: Decimal point : "{decimal_point}" Grouping positions : {grouping} Thousands separator: "{thousands_sep}" Monetary formatting: International currency symbol : "{int_curr_symbol!r}" Local currency symbol : {currency_symbol!r} Symbol precedes positive value : {p_cs_precedes} Symbol precedes negative value : {n_cs_precedes} Decimal point : "{mon_decimal_point}" Digits in fractional values : {frac_digits} Digits in fractional values, international : {int_frac_digits} Grouping positions : {mon_grouping} Thousands separator : "{mon_thousands_sep}" Positive sign : "{positive_sign}" Positive sign position : {p_sign_posn} Negative sign : "{negative_sign}" Negative sign position : {n_sign_posn} """ sign_positions { 0: 'Surrounded by parentheses', 1: 'Before value and symbol', 2: 'After value and symbol', 3: 'Before value', 4: 'After value', locale.CHAR_MAX: 'Unspecified', } info {} info.update(locale.localeconv()) info['p_sign_posn'] sign_positions[info['p_sign_posn']] info['n_sign_posn'] sign_positions[info['n_sign_posn']] print(template.format(**info))
Метод localeconv ()
возвращает словарь, содержащий соглашения о локали. Полный список имен и определений значений содержится в документации стандартной библиотеки.
Mac под управлением OS X 10.11.6 со всеми неустановленными переменными дает следующий результат:
$ Environment settings: LC_ALL = LC_CTYPE = LANG = LANGUAGE = Locale from environment: (None, None) Numeric formatting: Decimal point : "." Grouping positions : [] Thousands separator: "" Monetary formatting: International currency symbol : "''" Local currency symbol : '' Symbol precedes positive value : 127 Symbol precedes negative value : 127 Decimal point : "" Digits in fractional values : 127 Digits in fractional values, international : 127 Grouping positions : [] Thousands separator : "" Positive sign : "" Positive sign position : Unspecified Negative sign : "" Negative sign position : Unspecified
Выполнение того же сценария с набором переменных LANG
показывает, как меняются языковой стандарт и кодировка по умолчанию.
США ( en_US
):
$ Environment settings: LC_ALL = en_US LC_CTYPE = en_US LANG = en_US LANGUAGE = Locale from environment: ('en_US', 'ISO8859-1') Numeric formatting: Decimal point : "." Grouping positions : [3, 3, 0] Thousands separator: "," Monetary formatting: International currency symbol : "'USD '" Local currency symbol : '$' Symbol precedes positive value : 1 Symbol precedes negative value : 1 Decimal point : "." Digits in fractional values : 2 Digits in fractional values, international : 2 Grouping positions : [3, 3, 0] Thousands separator : "," Positive sign : "" Positive sign position : Before value and symbol Negative sign : "-" Negative sign position : Before value and symbol
Франция ( fr_FR
):
$ Environment settings: LC_ALL = fr_FR LC_CTYPE = fr_FR LANG = fr_FR LANGUAGE = Locale from environment: ('fr_FR', 'ISO8859-1') Numeric formatting: Decimal point : "," Grouping positions : [127] Thousands separator: "" Monetary formatting: International currency symbol : "'EUR '" Local currency symbol : 'Eu' Symbol precedes positive value : 0 Symbol precedes negative value : 0 Decimal point : "," Digits in fractional values : 2 Digits in fractional values, international : 2 Grouping positions : [3, 3, 0] Thousands separator : " " Positive sign : "" Positive sign position : Before value and symbol Negative sign : "-" Negative sign position : After value and symbol
Испания ( es_ES
):
$ Environment settings: LC_ALL = es_ES LC_CTYPE = es_ES LANG = es_ES LANGUAGE = Locale from environment: ('es_ES', 'ISO8859-1') Numeric formatting: Decimal point : "," Grouping positions : [127] Thousands separator: "" Monetary formatting: International currency symbol : "'EUR '" Local currency symbol : 'Eu' Symbol precedes positive value : 0 Symbol precedes negative value : 0 Decimal point : "," Digits in fractional values : 2 Digits in fractional values, international : 2 Grouping positions : [3, 3, 0] Thousands separator : "." Positive sign : "" Positive sign position : Before value and symbol Negative sign : "-" Negative sign position : Before value and symbol
Португалия ( pt_PT
):
$ Environment settings: LC_ALL = pt_PT LC_CTYPE = pt_PT LANG = pt_PT LANGUAGE = Locale from environment: ('pt_PT', 'ISO8859-1') Numeric formatting: Decimal point : "," Grouping positions : [] Thousands separator: " " Monetary formatting: International currency symbol : "'EUR '" Local currency symbol : 'Eu' Symbol precedes positive value : 0 Symbol precedes negative value : 0 Decimal point : "." Digits in fractional values : 2 Digits in fractional values, international : 2 Grouping positions : [3, 3, 0] Thousands separator : "." Positive sign : "" Positive sign position : Before value and symbol Negative sign : "-" Negative sign position : Before value and symbol
Польша ( pl_PL
):
$ Environment settings: LC_ALL = pl_PL LC_CTYPE = pl_PL LANG = pl_PL LANGUAGE = Locale from environment: ('pl_PL', 'ISO8859-2') Numeric formatting: Decimal point : "," Grouping positions : [3, 3, 0] Thousands separator: " " Monetary formatting: International currency symbol : "'PLN '" Local currency symbol : 'zł' Symbol precedes positive value : 1 Symbol precedes negative value : 1 Decimal point : "," Digits in fractional values : 2 Digits in fractional values, international : 2 Grouping positions : [3, 3, 0] Thousands separator : " " Positive sign : "" Positive sign position : After value Negative sign : "-" Negative sign position : After value
Валюта
Предыдущий пример выходных данных показывает, что при изменении локали обновляется настройка символа валюты и символа для отделения целых чисел от десятичных дробей. В этом примере просматривается несколько разных языковых стандартов, чтобы напечатать положительное и отрицательное значение валюты, отформатированное для каждого языкового стандарта.
locale_currency.py
import locale sample_locales [ ('USA', 'en_US'), ('France', 'fr_FR'), ('Spain', 'es_ES'), ('Portugal', 'pt_PT'), ('Poland', 'pl_PL'), ] for name, loc in sample_locales: locale.setlocale(locale.LC_ALL, loc) print('{:>10}: {:>10} {:>10}'.format( name, locale.currency(1234.56), locale.currency(-1234.56), ))
Результатом является эта небольшая таблица:
$ python3 locale_currency.py USA: $1234.56 -$1234.56 France: 1234,56 Eu 1234,56 Eu- Spain: 1234,56 Eu -1234,56 Eu Portugal: 1234.56 Eu -1234.56 Eu Poland: zł 1234,56 zł 1234,56-
Форматирование чисел
Числа, не относящиеся к валюте, также форматируются по-разному в зависимости от локали. В частности, изменяется символ grouping
, используемый для разделения больших чисел на читаемые фрагменты.
locale_grouping.py
import locale sample_locales [ ('USA', 'en_US'), ('France', 'fr_FR'), ('Spain', 'es_ES'), ('Portugal', 'pt_PT'), ('Poland', 'pl_PL'), ] print('{:>10} {:>10} {:>15}'.format( 'Locale', 'Integer', 'Float') ) for name, loc in sample_locales: locale.setlocale(locale.LC_ALL, loc) print('{:>10}'.format(name), end' ') print(locale.format_string('%10d', 123456, groupingTrue), end' ') print(locale.format_string('%15.2f', 123456.78, groupingTrue))
Чтобы отформатировать числа без символа валюты, используйте format_string ()
вместо currency ()
.
$ python3 locale_grouping.py Locale Integer Float USA 123,456 123,456.78 France 123456 123456,78 Spain 123456 123456,78 Portugal 123456 123456,78 Poland 123 456 123 456,78
Чтобы преобразовать числа в формате локали в нормализованный формат, не зависящий от языкового стандарта, используйте delocalize ()
.
locale_delocalize.py
import locale sample_locales [ ('USA', 'en_US'), ('France', 'fr_FR'), ('Spain', 'es_ES'), ('Portugal', 'pt_PT'), ('Poland', 'pl_PL'), ] for name, loc in sample_locales: locale.setlocale(locale.LC_ALL, loc) localized locale.format_string('%0.2f', 123456.78, groupingTrue) delocalized locale.delocalize(localized) print('{:>10}: {:>10} {:>10}'.format( name, localized, delocalized, ))
Знаки пунктуации при группировке удаляются, а десятичный разделитель всегда заменяется .
.
$ python3 locale_delocalize.py USA: 123,456.78 123456.78 France: 123456,78 123456.78 Spain: 123456,78 123456.78 Portugal: 123456,78 123456.78 Poland: 123 456,78 123456.78
Разбор чисел
Помимо создания вывода в различных форматах, модуль locale
помогает при синтаксическом анализе ввода. Он включает функции atoi ()
и atof ()
для преобразования строк в целые числа и значения с плавающей запятой на основе соглашений о числовом форматировании языкового стандарта.
locale_atof.py
import locale sample_data [ ('USA', 'en_US', '1,234.56'), ('France', 'fr_FR', '1234,56'), ('Spain', 'es_ES', '1234,56'), ('Portugal', 'pt_PT', '1234.56'), ('Poland', 'pl_PL', '1 234,56'), ] for name, loc, a in sample_data: locale.setlocale(locale.LC_ALL, loc) print('{:>10}: {:>9} => {:f}'.format( name, a, locale.atof(a), ))
Значения группировки и десятичного разделителя языкового стандарта распознаются анализатором.
$ python3 locale_atof.py USA: 1,234.56 => 1234.560000 France: 1234,56 => 1234.560000 Spain: 1234,56 => 1234.560000 Portugal: 1234.56 => 1234.560000 Poland: 1 234,56 => 1234.560000
Даты и время
Другой важный аспект локализации – форматирование даты и времени.
locale_date.py
import locale import time sample_locales [ ('USA', 'en_US'), ('France', 'fr_FR'), ('Spain', 'es_ES'), ('Portugal', 'pt_PT'), ('Poland', 'pl_PL'), ] for name, loc in sample_locales: locale.setlocale(locale.LC_ALL, loc) format locale.nl_langinfo(locale.D_T_FMT) print('{:>10}: {}'.format(name, time.strftime(format)))
В этом примере используется строка форматирования даты для языкового стандарта для печати текущей даты и времени.
$ python3 locale_date.py USA: Sun Dec 9 12:20:00 2018 France: Dim 9 déc 12:20:00 2018 Spain: dom 9 dic 12:20:00 2018 Portugal: Dom 9 Dez 12:20:00 2018 Poland: ndz 9 gru 12:20:00 2018
Смотрите также
- стандартная библиотечная документация для локали
- Примечания по переносу Python 2 на 3 для локали
- gettext – Каталоги сообщений для переводов.