Locale.setlocale: примеры (PYTHON)
locale.setlocale(category: int, locale: str or None): strОсновы функции locale.setlocale
Функция locale.setlocale() из модуля locale предназначена для установки, изменения или получения текущей локали (языковых и региональных настроек) для данной категории. Локаль влияет на форматирование чисел, дат, времени, валюты и сравнение строк.
Использование функции актуально при разработке интернационализированных приложений, где вывод информации должен соответствовать региональным стандартам пользователя.
Аргументы функции
locale.setlocale(category, locale=None)
category(обязательный): Константа, определяющая категорию настроек локали.locale.LC_ALL- все категории.locale.LC_COLLATE- для сравнения строк (strcoll, strxfrm).locale.LC_CTYPE- для символьных классов (isalpha, isdigit и т.д.) и преобразований (toupper, tolower).locale.LC_MONETARY- для форматирования денежных значений.locale.LC_NUMERIC- для форматирования чисел (разделитель дробной части).locale.LC_TIME- для форматирования даты и времени (strftime).locale.LC_MESSAGES- для сообщений системы (обычно для gettext).
locale(опциональный): Строка или кортеж, определяющий устанавливаемую локаль. Если равен пустой строке"", локаль берется из переменных окружения пользователя. Если равенNone, функция возвращает текущее значение локали для указанной категории. Формат строки:"[language[_territory][.codeset][@modifier]]", например,"ru_RU.UTF-8"или"en_US".
Возвращаемое значение
При вызове с аргументом locale (строкой), функция пытается установить локаль и возвращает ее имя в случае успеха. При вызове с locale=None, функция возвращает текущее значение локали для данной категории в виде строки. Если установить локаль не удалось, генерируется исключение locale.Error.
Краткие примеры использования
Получение текущей локали
import locale
current_locale = locale.setlocale(locale.LC_ALL, None)
print(current_locale)'C'
Установка системной локали по умолчанию
import locale
# Установка для всех категорий на основе переменных окружения
sys_locale = locale.setlocale(locale.LC_ALL, "")
print(f"Системная локаль: {sys_locale}")
# Проверка форматирования числа
print(locale.format_string("%d", 1234567, grouping=True))Системная локаль: ru_RU.UTF-8 1 234 567
Установка конкретной локали
import locale
# Установка русской локали для всех категорий
locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8')
# Форматирование валюты
locale.setlocale(locale.LC_MONETARY, 'ru_RU.UTF-8')
print(locale.currency(1234.56, grouping=True))1 234,56 руб.
Установка локали только для чисел и времени
import locale
from datetime import datetime
# Локаль для чисел (разделитель дробной части)
locale.setlocale(locale.LC_NUMERIC, 'de_DE')
print("Число:", locale.atof("1,234"))
# Локаль для времени
locale.setlocale(locale.LC_TIME, 'it_IT')
now = datetime.now()
print("Дата:", now.strftime("%A, %d %B %Y"))Число: 1.234 Дата: giovedì, 06 febbraio 2025
Похожие функции в Python
В Python для решения задач локализации и интернационализации применяют и другие модули.
Модуль gettext
Служит для перевода текстовых сообщений в приложении на разные языки. Работает с файлами переводов (.po, .mo). Применяется, когда требуется перевести строки интерфейса, а не форматировать данные.
import gettext
ru = gettext.translation('messages', localedir='locales', languages=['ru'])
ru.install()
print(_("Hello, world!")) # Если есть перевод, выведет "Привет, мир!"Строковые методы с локалью
Некоторые строковые операции, зависящие от локали (сравнение, регистр), могут использовать locale.strxfrm() или locale.strcoll(). Эти функции работают на основе текущей LC_COLLATE.
import locale
locale.setlocale(locale.LC_COLLATE, 'sv_SE')
sorted_list = sorted(["ängel", "zoo", "argo"], key=locale.strxfrm)
print(sorted_list)['argo', 'zoo', 'ängel']
Модуль babel
Сторонний пакет Babel предоставляет более гибкие и мощные инструменты для интернационализации: форматирование дат, чисел, списков, работа с временными зонами, извлечение строк для перевода. Его выбор предпочтителен для сложных проектов, где возможностей locale недостаточно.
Аналоги в других языках программирования
PHP: setlocale()
Функция setlocale() работает аналогично, принимая категории как целые числа или константы (LC_ALL, LC_TIME и др.). Возвращает установленную локаль или false при ошибке.
// PHP
$current = setlocale(LC_ALL, "0"); // Получить текущую
echo $current . "\n";
$new = setlocale(LC_TIME, "ru_RU.UTF-8");
echo strftime("%A");C четверг
JavaScript (Node.js): Intl объект
В JavaScript используется API Intl, который не устанавливает глобальную локаль, а создает форматтеры с конкретными настройками.
// JavaScript
const number = new Intl.NumberFormat('ru-RU').format(1234567.89);
console.log(number);
const date = new Intl.DateTimeFormat('de-DE').format(new Date());
console.log(date);1 234 567,89 6.2.2025
Java: Locale.setDefault()
В Java есть класс java.util.Locale. Метод setDefault() устанавливает локаль для всего JVM. Форматирование осуществляется через специфические классы (NumberFormat, DateFormat).
// Java
import java.util.Locale;
import java.text.NumberFormat;
Locale.setDefault(new Locale("ru", "RU"));
NumberFormat nf = NumberFormat.getInstance();
System.out.println(nf.format(1234567.89));1 234 567,89
C#: CultureInfo.CurrentCulture
В C# культура устанавливается для потока через CultureInfo.CurrentCulture (для форматирования) и CultureInfo.CurrentUICulture (для загрузки ресурсов).
// C#
System.Globalization.CultureInfo.CurrentCulture =
new System.Globalization.CultureInfo("fr-FR");
Console.WriteLine(12345.67.ToString("N"));12 345,67
Golang: Изменение локали отсутствует
В стандартной библиотеке Go нет аналога глобальной установки локали. Пакет golang.org/x/text предоставляет функции для специфического форматирования, но обычно используется подход с явной передачей локали в функции.
// Go (использование пакета golang.org/x/text/message)
import "golang.org/x/text/message"
p := message.NewPrinter(message.MatchLanguage("ru"))
p.Printf("%d\n", 1234567)1 234 567
Kotlin (JVM): java.util.Locale
Kotlin, работая на JVM, использует Java-механизмы локали.
// Kotlin
import java.util.Locale
import java.text.NumberFormat
Locale.setDefault(Locale("de", "DE"))
println(NumberFormat.getInstance().format(1234.56))1.234,56
Типичные ошибки
Неподдерживаемая локаль
Попытка установить локаль, недоступную в системе, приводит к исключению locale.Error.
import locale
try:
locale.setlocale(locale.LC_ALL, 'xyz_XYZ.UTF-8')
except locale.Error as e:
print(f"Ошибка: {e}")Ошибка: unsupported locale setting
Влияние на другие категории при установке LC_ALL
Установка LC_ALL перезаписывает все категории, что может вызвать неожиданное поведение, если ранее были заданы отдельные категории.
import locale
locale.setlocale(locale.LC_TIME, 'en_US')
locale.setlocale(locale.LC_NUMERIC, 'de_DE')
print("До LC_ALL:", locale.setlocale(locale.LC_TIME))
locale.setlocale(locale.LC_ALL, 'C') # Сбрасывает все
print("После LC_ALL:", locale.setlocale(locale.LC_TIME))До LC_ALL: en_US После LC_ALL: C
Использование не той кодировки в локали
Указание кодировки, которая не совпадает с системной или не поддерживается, может привести к ошибке или некорректному выводу.
import locale, sys
# Если локаль доступна, но с другой кодировкой, может не сработать
try:
locale.setlocale(locale.LC_ALL, 'ru_RU.CP1251') # На системе с UTF-8
print("Успешно")
except locale.Error:
print("Локаль с такой кодировкой недоступна")Локаль с такой кодировкой недоступна
Непонимание поведения locale=None
Иногда ожидают, что locale.setlocale(category, None) установит локаль по умолчанию, но на самом деле этот вызов только возвращает текущее значение.
import locale
# Неправильно: локаль не изменится
locale.setlocale(locale.LC_ALL, None)
print("Локаль после None:", locale.setlocale(locale.LC_ALL, None))Локаль после None: C
Изменения в последних версиях Python
В Python 3.11 была добавлена поддержка категории LC_MESSAGES на платформах Windows (работала только на Unix-подобных системах).
В Python 3.10 и более новых версиях улучшена обработка некорректных аргументов для некоторых функций модуля locale (например, locale.format_string).
Стоит отметить, что само использование модуля locale для форматирования чисел и валюты считается устаревшим подходом в пользу более гибкого и безопасного метода locale.format_string() с явным указанием формата, вместо старого locale.format().
Расширенные примеры
Временная установка локали в контексте
Для временного изменения локали внутри блока кода можно использовать менеджер контекста.
import locale
import contextlib
from datetime import datetime
@contextlib.contextmanager
def temporary_locale(category, locale_name):
original = locale.setlocale(category, None)
try:
locale.setlocale(category, locale_name)
yield
finally:
locale.setlocale(category, original)
print("Оригинальная дата:", datetime.now().strftime("%c"))
with temporary_locale(locale.LC_TIME, 'fr_FR'):
print("Французская дата:", datetime.now().strftime("%c"))
print("Восстановленная дата:", datetime.now().strftime("%c"))Оригинальная дата: Thu Feb 6 14:25:00 2025 Французская дата: jeu. févr. 6 14:25:00 2025 Восстановленная дата: Thu Feb 6 14:25:00 2025
Автоматическое определение доступных локалей
Можно попытаться найти и установить рабочую локаль, перебирая список возможных имен.
import locale
candidate_locales = ['ru_RU.UTF-8', 'ru_RU', 'Russian_Russia.1251', '']
for loc in candidate_locales:
try:
locale.setlocale(locale.LC_CTYPE, loc)
print(f"Установлена локаль: {loc}")
break
except locale.Error:
continue
else:
print("Не удалось установить русскую локаль.")Установлена локаль: ru_RU.UTF-8
Изменение только денежного формата для разных валют
Использование разных категорий позволяет тонко настроить вывод.
import locale
# Установка базовой локали (например, для США)
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
print("Цена в США:", locale.currency(99.99))
# Временная смена категории LC_MONETARY для евро
original_monetary = locale.setlocale(locale.LC_MONETARY, 'de_DE.UTF-8')
print("Цена в Германии:", locale.currency(99.99, symbol=True))
# Возврат денежного формата
locale.setlocale(locale.LC_MONETARY, original_monetary)
print("Цена снова в США:", locale.currency(99.99))Цена в США: $99.99 Цена в Германии: 99,99 € Цена снова в США: $99.99
Сравнение строк с учетом локали для сортировки
Использование locale.strxfrm в качестве ключа сортировки.
import locale
words = ["cafe", "café", "caff", "cāfe"]
print("Без учета локали:", sorted(words))
# Установка локали, где акценты влияют на порядок (например, французская)
locale.setlocale(locale.LC_COLLATE, 'fr_FR.UTF-8')
print("С учетом локали (fr_FR):", sorted(words, key=locale.strxfrm))
# Установка локали, где акценты игнорируются (например, английская)
locale.setlocale(locale.LC_COLLATE, 'en_US.UTF-8')
print("С учетом локали (en_US):", sorted(words, key=locale.strxfrm))Без учета локали: ['cafe', 'café', 'caff', 'cāfe'] С учетом локали (fr_FR): ['cafe', 'café', 'caff', 'cāfe'] С учетом локали (en_US): ['cafe', 'café', 'caff', 'cāfe']
Обработка чисел с разделителями из разных локалей
Функции locale.atoi, locale.atof корректно интерпретируют числа в соответствии с установленной LC_NUMERIC.
import locale
# Немецкий формат: запятая как разделитель дробной части
locale.setlocale(locale.LC_NUMERIC, 'de_DE')
num_str_de = "1.234,56" # Точка - разделитель тысяч, запятая - дробная часть
value_de = locale.atof(num_str_de)
print(f"de_DE: '{num_str_de}' -> {value_de}")
# Английский формат: точка как разделитель дробной части
locale.setlocale(locale.LC_NUMERIC, 'en_US')
num_str_en = "1,234.56" # Запятая - разделитель тысяч, точка - дробная часть
value_en = locale.atof(num_str_en)
print(f"en_US: '{num_str_en}' -> {value_en}")de_DE: '1.234,56' -> 1234.56 en_US: '1,234.56' -> 1234.56