modern-i18n — это легковесная библиотека для интернационализации Python-проектов. Она позволяет легко управлять переводами, использовать параметризованные строки для форматирования текста. Подходит для небольших и крупных проектов.

Для кого это статья?

Статья предназначена для разработчиков проектов на Python, которые хотят внедрить в свой проект интернационализацию (поддержку нескольких языков).

Введение

В современных приложениях, особенно тех, что используются в международной среде, поддержка нескольких языков (интернационализация — i18n) является критически важным аспектом. Modern-i18n — это библиотека для Python, которая упрощает и делает процесс локализации более эффективным и понятным. Она предлагает удобный API, поддерживает JSON-формат для хранения переводов и обеспечивает гибкость настройки.

Почему я разработал собственный i18n?

Основные причины:

  • Упрощение работы с переводами

    Многие популярные библиотеки i18n требуют сложной настройки и обладают избыточным API. Я хотел создать решение, которое будет простым, понятным и удобным для использования.

  • Минимизация зависимостей

    Некоторые библиотеки i18n требуют установки дополнительных пакетов, что может усложнять развертывание. Modern-i18n работает без них.

  • Легкость и производительность

    Библиотека modern-i18n не зависит от сторонних библиотек и легко интегрируется в любой проект. Она загружает только необходимые данные и использует механизм кэширования для повышения скорости работы.

  • Гибкость

    Библиотека может использоваться как в чистых проектах на Python, так и с web-фреймворками (Flask, Django и др.).

  • Самостоятельность и контроль

    Создавая собственную реализацию, я получил возможность полностью контролировать её поведение, улучшать её по мере необходимости и адаптировать под конкретные задачи проекта.

Установка

Для установки библиотеки воспользуйтесь пакетным менеджером pip:

pip install modern-i18n

Структура проекта

Для внедрения i18n необходимо создать в свой проект новые папки и файлы. Пример типовой структуры проекта после настройки библиотеки modern-i18n:

project/
├── i18n/              # ? Модуль интернационализации
│   └── config.py      # ? Конфигурационный файл: язык по умолчанию, путь к переводам и т.д.
│
├── locale/            # ? Директория с переводами (локализациями)
│   ├── en/            # ? Английская локаль
│   │   └── translation.json  # ? Файл с переводами на английский язык
│   └── ru/            # ? Русская локаль
│       └── translation.json  # ? Файл с переводами на русский язык
│
└── example.py         # ? Пример использования функции перевода

Конфигурация

Все настройки библиотеки находятся в файле i18n/config.py. Пример базовой конфигурации:

import os
from pathlib import Path

from modern_i18n.i18n import I18n

project_root = Path(__file__).resolve().parent.parent
LOCALE_PATH = os.path.join(project_root, 'locale')

config = {
    'locale_path': LOCALE_PATH,  # Путь к директории с переводами
    'locales': ['ru', 'en'],  # Список доступных языков
    'default_locale': 'ru',  # Язык по умолчанию
    'default_encoding': 'UTF-8'  # Кодировка для файлов перевода по умолчанию 'UTF-8'
}

i18n = I18n(config)
t = i18n.translate
  • В файле i18n/config.py настраиваются основные параметры: список доступных языков, язык по умолчанию, путь к директории с переводами и дополнительные опции.

  • Все переводы хранятся в формате JSON внутри директории locale, где каждая локаль имеет свою собственную папку.

Формат переводов

Переводы хранятся в файлах translation.json, где каждый ключ — это оригинальная фраза, а значение — её перевод на нужный язык.

Пример для английского языка (locale/en/translation.json):

{
  "Итого {a}+{b}={total}": "Total {a}+{b}={total}.",
  "Количество языков на планете бесчисленное множество": "There are countless languages on the planet",
  "Ограничение длины строки: {str:.6}": "String length limit: {str:.6}",
  "Процент: {percent:.0%}": "Percentage: {percent:.0%}",
  "Процент: {percent:.1%}": "Percentage: {percent:.1%}",
  "Процент: {percent:.2%}": "Percentage: {percent:.2%}",
  "Сегодня: {date:%A, %B %d, %Y}": "Today: {date:%A, %B %d, %Y}",
  "Сегодня: {date:%d.%m.%Y}": "Today: {date:%d.%m.%Y}",
  "Сегодня: {date}": "Today: {date}",
  "Число с плавающей точкой: {number:.0f}": "Floating point number: {number:.0f}",
  "Число с плавающей точкой: {number:.3f}": "Floating point number: {number:.3f}"
}

Пример для русского языка (locale/ru/translation.json):

{
  "Итого {a}+{b}={total}": "Итого {a}+{b}={total}.",
  "Количество языков на планете бесчисленное множество": "Количество языков на планете бесчисленное множество",
  "Ограничение длины строки: {str:.6}": "Ограничение длины строки: {str:.6}",
  "Процент: {percent:.0%}": "Процент: {percent:.0%}",
  "Процент: {percent:.1%}": "Процент: {percent:.1%}",
  "Процент: {percent:.2%}": "Процент: {percent:.2%}",
  "Сегодня: {date:%A, %B %d, %Y}": "Сегодня: {date:%A, %B %d, %Y}",
  "Сегодня: {date:%d.%m.%Y}": "Сегодня: {date:%d.%m.%Y}",
  "Сегодня: {date}": "Сегодня: {date}",
  "Число с плавающей точкой: {number:.0f}": "Число с плавающей точкой: {number:.0f}",
  "Число с плавающей точкой: {number:.3f}": "Число с плавающей точкой: {number:.3f}"
}

⚠️ Важно: все ключи должны быть одинаковыми во всех файлах, чтобы обеспечить корректное сопоставление.

ℹ️ По моему опыту по внедрению i18n в большие проекты, в качестве ключей рекомендую использовать те названия, которые уже есть у Вас на проекте.

Например, у Вас есть строковые переменные, которые нужно интернационализировать.

До внедрения i18n:

s = 'Количество языков на планете бесчисленное множество'

Вы просто берете эту строку и оборачиваете ее в функцию t.

После внедрения i18n:

from i18n.config import t

s = t('Количество языков на планете бесчисленное множество', locale='en')

В результате получаете ту же читаемость кода, что и была. Плюс избавляет Вас от придумывания ключей, что сэкономит Вам много времени, особенно когда проект большой.

Использование библиотеки

После конфигурации вы можете использовать функцию t для получения перевода.

from i18n.config import t

print(t('Количество языков на планете бесчисленное множество'))  # -> Количество языков на планете бесчисленное множество
# Перевод с указанием локали
print(t('Количество языков на планете бесчисленное множество', locale='en'))  # -> There are countless languages on the planet

Перевод с параметрами

print(t('Итого {a}+{b}={total}', a=5, b=10, total=15))  # -> Итого 5+10=15.
print(t('Итого {a}+{b}={total}', locale='en', a=5, b=10, total=15))  # -> Total 5+10=15.

Форматируемый перевод

Библиотека позволяет гибко форматировать строки, используя именованные аргументы, а также спецификаторы формата для чисел, строк и дат.

import datetime

# Число с плавающей точкой
print(t("Число с плавающей точкой: {number:.3f}", locale='en', number=3.14159))  # -> Floating point number: 3.142
print(t("Число с плавающей точкой: {number:.0f}", locale='en', number=3.5))  # -> Floating point number: 4

# Проценты
print(t("Процент: {percent:.2%}", locale='en', percent=0.736))  # -> Percentage: 73.60%
print(t("Процент: {percent:.1%}", locale='en', percent=0.736))  # -> Percentage: 73.6%
print(t("Процент: {percent:.0%}", locale='en', percent=0.736))  # -> Percentage: 74%

# Форматирование даты
today = datetime.date.today()
print(t("Сегодня: {date}", date=today))  # -> Сегодня: 2025-07-10
print(t("Сегодня: {date:%d.%m.%Y}", date=today))  # -> Сегодня: 10.07.2025
print(t("Сегодня: {date:%A, %B %d, %Y}", locale='en', date=today))  # -> Today: Thursday, July 10, 2025

# Ограничение длины строки
print(t("Ограничение длины строки: {str:.6}", locale='en', str="Привет мир!"))  # -> String length limit: Привет

Обработка отсутствующих ключей

Если ключ не найден, библиотека выдаст предупреждение и вернёт исходную строку:

print(t('Ключ не существует'))  # Warning -> Ключ не существует

Заключение

Modern-i18n — это мощная и простая в использовании библиотека для интернационализации Python-проектов. Она позволяет быстро настраивать локализацию, поддерживает работу с несколькими языками и параметризованными строками. Благодаря своей гибкости и лёгкости, она станет отличным выбором для разработчиков, которым нужно создать многоязычное приложение без лишней сложности.

Эта библиотека используется в реальных проектах и продолжает развиваться. Если вы сталкиваетесь с задачей локализации в Python-приложениях, обязательно попробуйте modern-i18n — возможно, она станет вашим идеальным выбором.

Ссылка на библиотеку

Буду рад обратной связи. В комментариях напишите, а как Вы решаете данную задачу.

Комментарии (7)


  1. Tishka17
    10.07.2025 15:56

    Минималистично API это, конечно, хорошо, но

    1. Какие инструменты для переводчиков вы предлагаете?

    2. Как происходит плурализация? (1 яблоко, 2 яблока, 5 яблок / 1 apple, 2 apples, 5 apples)

    3. Как насчет локализации чисел? (1 000,15 vs 1,000.15)


    1. andreymal
      10.07.2025 15:56

      И падежи ещё (1 яблоком, 2 яблоками), я сейчас страдаю от их отсутствия в gettext


      1. Tishka17
        10.07.2025 15:56

        Имхо, падежи не меняются диамически, они не зависят от подставляемых данных. Вы просто формируете фразу сразу в нужном падеже. Но да, так мы ограничены в динамической сборке из кусков


        1. andreymal
          10.07.2025 15:56

          Подставляемые данные зависят от падежей. А среднестатистический англоязычный разработчик часто забывает, что в других языках падежей бывает больше чем в английском, и в итоге из какого-нибудь «%s угостил %s %d %s» мы получаем «Вася угостил Петя 1 яблоко»

          Ах да, попутно и про род можно вспомнить, а то какое-нибудь «Получен 1 яблоко» тоже не круто


    1. Abbas_I Автор
      10.07.2025 15:56

      1. По сопровождению translation.json файлов и их наполнению я использую плагины в ide и отдельные приложения предназначенные чисто для этих целей.

      2. Плюрализации в этой библиотеки нет, возможно в будущем я добавлю ее. В проектах 90% случаев плюрализация скорее всего Вам не понадобится. Если рассматривать пример с яблоками, можно переназвать это как: "Яблок: {n} шт."

        Для плюрализации, чтобы это хорошо работало нужно учитывать большое количество факторов: род (мужской, женский, средний), число (множественное, единственное), контест в предложении, падежи, ешё это в разных языках это все по разному. В итоге Вы откажитесь от этой затеи и придете к нейтральным словам (предложениям).

      3. По локализации чисел, валют, дат, номеров телефонов здесь я могу предложить использовать сторонние библиотеки, например locale (https://metanit.com/python/tutorial/6.3.php)


  1. A-V-tor
    10.07.2025 15:56

    Это ваша библиотека? Ни одной звезды, 4 коммита за все время. Вы тогда хотя бы скажите об этом, а то выглядит не очень безопасно.


    1. Abbas_I Автор
      10.07.2025 15:56

      Это библиотека абсолютно безопасна в использовании, в ней нет сторонних зависимостей, все решение создано на чистом python. Она разрабатывалась специально для проектов разного уровня сложности с которыми мне приходилось работать.