Skip to main content

Python i18n: kompletny przewodnik po lokalizacji

Skonfiguruj python-i18n z plikami tłumaczeń JSON lub YAML, obsłuż symbole zastępcze i liczbę mnogą, a następnie zautomatyzuj tłumaczenia za pomocą AI.

1

Instalacja python-i18n

python-i18n to lekka biblioteka do internacjonalizacji Pythona. Obsługuje pliki tłumaczeń JSON i YAML, zagnieżdżone klucze, interpolację symboli zastępczych oraz liczbę mnogą bez dodatkowej konfiguracji.

Terminal
pip install python-i18n
python-i18n domyślnie obsługuje JSON. Aby korzystać z plików YAML, zainstaluj opcjonalną zależność poleceniem pip install python-i18n[YAML], które dodaje PyYAML.
Terminal
# To use YAML translation files instead of JSON:
pip install python-i18n[YAML]
2

Konfigurowanie tłumaczeń

Ustaw format pliku, dodaj ścieżki do plików tłumaczeń oraz skonfiguruj domyślny i rezerwowy język. Zaimportuj tę konfigurację w punkcie wejścia aplikacji przed pierwszym wywołaniem funkcji tłumaczącej.

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 musi wskazywać katalog zawierający pliki tłumaczeń, a nie konkretny plik. Jeśli zamiast tłumaczeń zwracane są surowe klucze, sprawdź poprawność load_path oraz zgodność nazw plików z kodami języków, na przykład en.json i de.json.
3

Tworzenie plików tłumaczeń

Utwórz po jednym pliku dla każdego języka w formacie JSON lub YAML. Użyj zagnieżdżonych kluczy, aby uporządkować teksty według funkcji lub strony. Zachowaj język źródłowy, zwykle angielski, jako jedno źródło referencyjne.

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"
  }
}
Nazywaj klucze według ich znaczenia, a nie miejsca wyświetlania: 'cart.item_count' jest lepsze niż 'homepage_cart_label'. Klucze powinny przetrwać przeprojektowanie interfejsu.
4

Używanie tłumaczeń w kodzie

Wywołaj i18n.t() ze ścieżką klucza rozdzieloną kropkami, aby wyszukać przetłumaczony tekst. Dla pojedynczego wywołania można nadpisać język bez zmiany ustawienia globalnego.

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"
Zagnieżdżone klucze używają notacji kropkowej: i18n.t('nav.home'). Jeśli klucze JSON zawierają dosłowne kropki, python-i18n zinterpretuje je jako separatory zagnieżdżenia. Unikaj kropek w nazwach kluczy.
5

Symbole zastępcze i liczba mnoga

python-i18n obsługuje interpolację symboli zastępczych za pomocą składni %{name} oraz podstawową liczbę mnogą przez podklucze 'zero', 'one' i 'many'. Dla obu funkcji przekaż argumenty nazwane do 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"
Obsługa liczby mnogiej w python-i18n korzysta z trzech kategorii: zero, one i many. Wystarczają one dla angielskiego i wielu innych języków, ale nie obejmują wszystkich reguł CLDR, takich jak few, two i other. W językach o złożonej odmianie, takich jak arabski, rosyjski lub polski, przypadki brzegowe mogą wymagać obsługi ręcznej albo bardziej zaawansowanej biblioteki.
6

Zmiana języka podczas działania

Zmień aktywny język globalnie przez i18n.set('locale', code) lub nadpisz go dla pojedynczego wywołania argumentem locale. W aplikacjach internetowych wykryj preferowany język użytkownika z żądania i ustaw go przed renderowaniem.

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', ...) zmienia język globalnie. Na wielowątkowych serwerach internetowych, takich jak gunicorn z procesami roboczymi lub Django, może to powodować wyścigi: jedno żądanie zmienia język podczas renderowania drugiego. Aby temu zapobiec, użyj nadpisania dla pojedynczego wywołania lub pamięci lokalnej wątku.
7

Inteligentny łańcuch rezerwowy z python-i18n-locale-chain

Domyślnie python-i18n obsługuje tylko jeden język rezerwowy. Gdy brakuje tłumaczeń pt-BR, biblioteka od razu przechodzi do angielskiego i ignoruje poprawne tłumaczenia pt-PT. python-i18n-locale-chain rozwiązuje ten problem za pomocą konfigurowalnych łańcuchów dla 75 wariantów regionalnych.

python-i18n-locale-chain to bezpłatny pakiet open source. Jedno wywołanie funkcji aktywuje 75 wbudowanych łańcuchów rezerwowych dla regionalnych wariantów języka chińskiego, portugalskiego, hiszpańskiego, francuskiego, niemieckiego, włoskiego, niderlandzkiego, angielskiego, arabskiego, norweskiego i malajskiego.
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()
Najważniejsze łańcuchy do przetestowania: pt-BR -> pt-PT -> pt -> en (portugalski), es-MX -> es-419 -> es -> en (hiszpański) oraz zh-Hant-HK -> zh-Hant-TW -> zh-Hant -> en (tradycyjny chiński). Obejmują one najczęstsze regionalne scenariusze rezerwowe.
8

Automatyzacja tłumaczeń

Po ukończeniu konfiguracji i18n przetłumacz pliki językowe za pomocą AI. Poproś asystenta AI w środowisku programistycznym o przetłumaczenie pliku źródłowego lub użyj CLI i18n Agent w pipeline 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
Tłumacz przyrostowo. Po dodaniu nowych kluczy do pliku źródłowego przetłumacz tylko różnicę zamiast ponownie generować wszystkie pliki. Pozwoli to zachować tłumaczenia sprawdzone przez człowieka.

Automatyczna kontrola jakości tłumaczeń

Wykryj brakujące klucze i uszkodzone symbole zastępcze przed wydaniem za pomocą i18n-validate. Przetestuj interfejs przy użyciu pseudotłumaczeń z i18n-pseudo, zanim pojawią się właściwe tłumaczenia.

Częste pułapki

Zamiast tłumaczeń zwracane są surowe klucze

Możliwe przyczyny: load_path nie jest ustawione lub wskazuje niewłaściwy katalog, file_format nie odpowiada rozszerzeniom albo nazwy plików nie odpowiadają kodom języków. Sprawdź, czy i18n.load_path zawiera właściwy katalog oraz czy pliki mają prawidłowe nazwy, na przykład en.json i de.json.

Pliki YAML nie są wczytywane

python-i18n wymaga PyYAML do obsługi YAML, ale nie instaluje go domyślnie. Użyj polecenia pip install python-i18n[YAML]. Bez tej zależności pliki YAML są po cichu ignorowane, a tłumaczenia zwracają symbole brakujących kluczy.

Wyszukiwanie zagnieżdżonych kluczy nie działa

python-i18n używa notacji kropkowej dla zagnieżdżonych kluczy: i18n.t('nav.home'). Jeśli JSON zawiera płaskie klucze z kropkami w nazwie, na przykład pojedynczy klucz 'nav.home', biblioteka interpretuje go jako zagnieżdżone wyszukiwanie i zgłasza błąd. Zamiast tego użyj rzeczywistych zagnieżdżonych obiektów JSON.

Zmiany języka przenikają między żądaniami

i18n.set('locale', ...) jest operacją globalną. Na serwerach wielowątkowych jedno żądanie może zmienić język podczas renderowania innego. Użyj argumentu locale= w poszczególnych wywołaniach i18n.t() lub ustaw język w pamięci lokalnej wątku za pomocą middleware.

Zalecana struktura plików

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
└── ...

Wypróbuj i18n Agent

Upuść tutaj plik tłumaczenia

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

lub kliknij, aby go wybrać

Języki docelowe

Rejestracja nie jest wymaganaNatychmiastowa wycena

Łańcuch rezerwowy z python-i18n-locale-chain

Gdy brakuje klucza tłumaczenia w regionalnych ustawieniach takich jak es-419, python-i18n od razu przechodzi do języka domyślnego zamiast najpierw sprawdzić nadrzędny język 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'],
'}')

# Usage: t('greeting', locale='es') — falls back through chain

Zobacz przewodnik po mechanizmach locale fallback, aby poznać pełną listę obsługiwanych frameworków i 75 wbudowanych łańcuchów. Learn more →

Częste pytania