Skip to main content

Python i18n: пълно ръководство за локализация

Настройте python-i18n с JSON или YAML файлове с преводи, обработвайте заместители и множествено число, а след това автоматизирайте преводите с ИИ.

1

Инсталирайте python-i18n

python-i18n е олекотена библиотека за интернационализация на Python. Тя поддържа JSON и YAML файлове с преводи, вложени ключове, заместване на стойности и множествено число без допълнителна конфигурация.

Terminal
pip install python-i18n
python-i18n поддържа JSON по подразбиране. За YAML файлове с преводи инсталирайте незадължителната зависимост за YAML чрез pip install python-i18n[YAML], която добавя PyYAML.
Terminal
# To use YAML translation files instead of JSON:
pip install python-i18n[YAML]
2

Конфигурирайте преводите

Задайте файловия формат, добавете пътищата до файловете с преводи и конфигурирайте локала по подразбиране и резервния локал. Импортирайте тази конфигурация във входната точка на приложението, преди да извикате функция за превод.

i18n_config.py
import i18n

# Set the file format (json or yaml)
i18n.set("file_format", "json")

# Add the directory containing your translation files
i18n.load_path.append("translations/")

# Set the default locale
i18n.set("locale", "en")

# Set the fallback locale (used when a key is missing)
i18n.set("fallback", "en")

# Enable/disable error on missing translations
i18n.set("error_on_missing_translation", False)
load_path трябва да сочи към директорията, която съдържа файловете с преводи, а не към конкретен файл. Ако преводите връщат необработените ключове, проверете дали load_path е правилен и дали имената на файловете съответстват на кодовете на локалите (например en.json, de.json).
3

Създайте файлове с преводи

Създайте по един файл за всеки език във формат JSON или YAML. Използвайте вложени ключове, за да организирате низовете по функционалност или страница. Поддържайте изходния език (обикновено английски) като единствен достоверен източник.

translations/en.json
// translations/en.json
{
  "greeting": "Hello!",
  "welcome": "Welcome to our application",
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "cart": {
    "item_count": "%{count} item(s) in your cart"
  }
}

// translations/de.json
{
  "greeting": "Hallo!",
  "welcome": "Willkommen in unserer Anwendung",
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "settings": "Einstellungen"
  },
  "cart": {
    "item_count": "%{count} Artikel in Ihrem Warenkorb"
  }
}
Именувайте ключовете според това, което описват, а не според мястото, на което се показват: 'cart.item_count' е по-подходящо от 'homepage_cart_label'. Ключовете трябва да останат приложими и след промени в дизайна на потребителския интерфейс.
4

Използвайте преводите в кода

Извикайте i18n.t() с път до ключ, разделен с точки, за да намерите преведения низ. Можете да замените локала за отделно извикване, без да променяте глобалната настройка.

app.py
import i18n

# Simple translation
print(i18n.t("greeting"))          # "Hello!"
print(i18n.t("nav.home"))          # "Home"
print(i18n.t("nav.about"))         # "About"

# Translation with a specific locale
print(i18n.t("greeting", locale="de"))   # "Hallo!"
print(i18n.t("nav.home", locale="ja"))   # "ホーム"

# Missing key returns a placeholder
print(i18n.t("missing.key"))       # "Missing.Key"
Вложените ключове използват нотация с точки: i18n.t('nav.home'). Ако ключовете във Вашия JSON съдържат буквални точки, python-i18n ще ги интерпретира като разделители за вложени нива. Не използвайте точки в имената на ключовете.
5

Заместители и множествено число

python-i18n поддържа заместване на стойности чрез синтаксиса %{name} и основни форми за множествено число чрез подключовете 'zero', 'one' и 'many'. Подайте именувани аргументи към i18n.t() и за двете възможности.

Placeholders
# translations/en.json
# {
#   "welcome_user": "Welcome, %{name}!",
#   "order_status": "Order #%{order_id}: %{status}",
#   "file_size": "File size: %{size} %{unit}"
# }

import i18n

# Single placeholder
print(i18n.t("welcome_user", name="Alice"))
# "Welcome, Alice!"

# Multiple placeholders
print(i18n.t("order_status", order_id=12345, status="shipped"))
# "Order #12345: shipped"

# Reusable with different values
print(i18n.t("file_size", size=2.5, unit="MB"))
# "File size: 2.5 MB"

print(i18n.t("file_size", size=800, unit="KB"))
# "File size: 800 KB"
Pluralization
# translations/en.json
# {
#   "inbox": {
#     "zero": "No messages",
#     "one": "1 message",
#     "many": "%{count} messages"
#   }
# }

import i18n

print(i18n.t("inbox", count=0))    # "No messages"
print(i18n.t("inbox", count=1))    # "1 message"
print(i18n.t("inbox", count=42))   # "42 messages"
Множественото число в python-i18n използва три категории: zero, one и many. Това е достатъчно за английски и много други езици, но не поддържа пълния набор от правила на CLDR (few, two, other). За езици със сложни форми за множествено число, като арабски, руски или полски, може да се наложи да обработвате граничните случаи ръчно или да използвате по-разширена библиотека.
6

Смяна на локала по време на изпълнение

Сменете активния локал глобално чрез i18n.set('locale', code) или го заменете за отделно извикване чрез именувания аргумент locale. В уеб платформи определете предпочитания от потребителя език от заявката и задайте локала преди визуализиране.

Locale switching
import i18n

# Set locale globally
i18n.set("locale", "de")
print(i18n.t("greeting"))           # "Hallo!"

# Switch to Japanese
i18n.set("locale", "ja")
print(i18n.t("greeting"))           # "こんにちは!"

# Override per-call without changing global locale
i18n.set("locale", "en")
print(i18n.t("greeting"))           # "Hello!"
print(i18n.t("greeting", locale="de"))  # "Hallo!"
app.py
from flask import Flask, request, g
import i18n

app = Flask(__name__)

i18n.set("file_format", "json")
i18n.load_path.append("translations/")

SUPPORTED_LOCALES = ["en", "de", "ja", "es", "fr"]

@app.before_request
def set_locale():
    # Check URL parameter, cookie, then Accept-Language header
    locale = request.args.get("lang")
    if not locale:
        locale = request.cookies.get("locale")
    if not locale:
        locale = request.accept_languages.best_match(SUPPORTED_LOCALES)
    g.locale = locale or "en"
    i18n.set("locale", g.locale)

@app.route("/")
def index():
    return i18n.t("welcome")
i18n.set('locale', ...) променя локала глобално. В многонишкови уеб сървъри (gunicorn с workers, Django) това може да предизвика състояния на надпревара, при които една заявка променя локала, докато друга се визуализира. Използвайте замяна на локала за отделните извиквания или съхранение, локално за нишката, за да избегнете проблема.
7

Интелигентни резервни локали с python-i18n-locale-chain

По подразбиране python-i18n поддържа само един резервен локал. Когато за потребител с pt-BR няма преводи на pt-BR, библиотеката преминава направо към резервния английски, като пренебрегва наличните преводи на pt-PT. python-i18n-locale-chain решава проблема чрез конфигурируеми резервни вериги, които обхващат 75 варианта на локали.

python-i18n-locale-chain е безплатен пакет с отворен код. Едно извикване на функция активира 75 вградени резервни вериги за регионални варианти на локали на китайски, португалски, испански, френски, немски, италиански, нидерландски, английски, арабски, норвежки и малайски.
Terminal
pip install python-i18n-locale-chain
i18n_config.py
from locale_chain import configure
import i18n

i18n.set("file_format", "json")
i18n.load_path.append("translations/")

# Activate smart fallback chains (75 built-in chains)
configure()

# Now pt-BR falls back to pt-PT -> pt -> en (instead of just en)
result = i18n.t("greeting", locale="pt-BR")

# es-MX falls back to es-419 -> es -> en
result = i18n.t("greeting", locale="es-MX")

# zh-Hant-HK falls back to zh-Hant-TW -> zh-Hant -> en
result = i18n.t("greeting", locale="zh-Hant-HK")
Advanced configuration
from locale_chain import configure, reset

# Override specific chains
configure(overrides={
    "pt-BR": ["pt"],         # Skip pt-PT, go straight to pt
    "ja-JP": ["ja"],         # Add a new chain
})

# Full custom map (no defaults)
configure(
    fallbacks={"pt-BR": ["pt-PT"]},
    merge_defaults=False
)

# Use German as final fallback instead of English
configure(default_locale="de")

# Restore original i18n.t() behaviour
reset()
Най-важните вериги за тестване са: pt-BR -> pt-PT -> pt -> en (португалски), es-MX -> es-419 -> es -> en (испански), zh-Hant-HK -> zh-Hant-TW -> zh-Hant -> en (традиционен китайски). Те обхващат най-често срещаните сценарии за регионален резервен превод.
8

Автоматизирайте преводите

След като настройката за i18n е готова, преведете файловете за локалите чрез ИИ. Във Вашата IDE поискайте от асистента си с ИИ да преведе изходния файл или използвайте CLI на i18n Agent в пайплайна за CI/CD.

Terminal
# In your IDE, ask your AI assistant:
> Translate translations/en.json to German, Japanese, and Spanish

translations/de.json created (1.2s)
translations/ja.json created (1.5s)
translations/es.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate translations/en.json --lang de,ja,es
Превеждайте поетапно. Когато добавите нови ключове към изходния файл, преведете само разликите, вместо да създавате наново всички файлове. Така ще запазите преводите, които вече са прегледани от човек.

Автоматизирайте контрола на качеството на превода

Откривайте липсващи ключове и повредени заместители с i18n-validate, преди да достигнат до потребителите. Тествайте потребителския интерфейс с псевдопреводи чрез i18n-pseudo, преди да са готови истинските преводи.

Често срещани затруднения

Преводите връщат необработени ключове

Причини: load_path не е зададен или сочи към неправилната директория, file_format не съответства на файловите разширения или имената на файловете не съответстват на кодовете на локалите. Проверете дали i18n.load_path съдържа правилната директория и дали файловете са именувани правилно (например en.json, de.json).

YAML файловете не се зареждат

python-i18n изисква PyYAML за поддръжка на YAML, но пакетът не се инсталира по подразбиране. Инсталирайте го чрез pip install python-i18n[YAML]. Без него YAML файловете се пренебрегват без предупреждение, а преводите връщат заместители за липсващи ключове.

Търсенето на вложени ключове е неуспешно

python-i18n използва нотация с точки за вложените ключове: i18n.t('nav.home'). Ако Вашият JSON използва плоски ключове с точки в името (например 'nav.home' като един ключ), библиотеката го интерпретира като вложено търсене и операцията е неуспешна. Вместо това използвайте действително вложени JSON обекти.

Промените на локала се пренасят между заявките

i18n.set('locale', ...) е глобална операция. В многонишкови сървъри една заявка може да промени локала, докато друга се визуализира. Използвайте именувания аргумент locale= при отделните извиквания на i18n.t() или задавайте локала в съхранение, локално за нишката, чрез междинен софтуер.

Препоръчителна файлова структура

Project Structure
my-python-app/
├── translations/
│   ├── en.json           # Source language (JSON)
│   ├── de.json           # German
│   ├── ja.json           # Japanese
│   ├── es.json           # Spanish
│   └── pt-BR.json        # Brazilian Portuguese
├── app.py                # Application entry point
├── i18n_config.py        # i18n setup and configuration
├── requirements.txt      # pip dependencies
└── pyproject.toml        # Project metadata

# Or with YAML files:
my-python-app/
├── translations/
│   ├── en.yml
│   ├── de.yml
│   └── ja.yml
├── app.py
└── ...

Изпробвайте i18n Agent сега

Пуснете тук Вашия файл за превод

JSON, YAML, PO, XML, CSV, Markdown, Properties

или натиснете, за да изберете файл

Целеви езици

Не се изисква регистрацияНезабавна оценка

Резервни локали с python-i18n-locale-chain

Когато ключ за превод липсва в регионален локал като es-419, python-i18n преминава направо към локала по подразбиране, вместо първо да провери родителския локал es.

Terminal
pip install python-i18n-locale-chain
Configuration
from i18n_locale_chain import configure_chain

configure_chain('{')
    'es': ['en', 'ru'],
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
'}')

# Употреба: t('greeting', locale='es') — преминава по резервната верига

Вижте нашето ръководство за резервна локализация за пълния списък с поддържани платформи и 75 вградени вериги. Learn more →

Често задавани въпроси