Dịch trọn cả thông điệp
bằng t-string của Python¶
gettext-tstrings nối t-string của Python 3.14+ với các catalog gettext tiêu
chuẩn và bộ công cụ Babel. Giá trị và định dạng ở nguyên trong mã ứng dụng;
người dịch làm việc với những thông điệp trọn vẹn và các placeholder {name}
giản dị:
import gettext
from gettext_tstrings import Translator
_ = Translator(gettext.translation("messages", localedir="locales"))
name = "Ada"
print(_(t"Hello {name}")) # with a Japanese catalog: こんにちは Ada
Catalog chứa Hello {name}. Một bản dịch có thể chuyển chỗ hoặc lặp lại
{name}. Nếu nó bỏ mất, đổi tên hay thêm định dạng cho placeholder, khâu kiểm
tra catalog sẽ báo lỗi. Nếu một mục sai vẫn lọt tới production, thư viện ghi một
cảnh báo và kết xuất thông điệp nguồn thay vì làm chương trình đổ vỡ.
Bắt đầu hướng dẫn nhập môn năm phút So sánh các lựa chọn khác
Alpha · Python 3.14+ · catalog PO/MO tiêu chuẩn · không phụ thuộc bên thứ ba lúc chạy
Trang này thực hành đúng điều nó viết: mọi phiên bản ngôn ngữ —
thanh điều hướng, nhãn, và báo cáo build có xử lý số nhiều — đều được kết xuất
từ các catalog PO bởi chính
gettext-tstrings.
Thư viện này có hợp với bạn không?¶
Hợp ngay hôm nay khi ứng dụng của bạn chạy trên Python 3.14 trở lên; bạn đã dùng gettext và Babel, hoặc muốn áp dụng quy trình PO/MO của chúng; và bạn muốn cú pháp t-string với các placeholder có tên được kiểm tra trước khi kết xuất.
Chưa hợp khi bạn cần Python 3.13 hoặc cũ hơn; bạn đòi hỏi một API Python ổn định — đây là bản alpha, và đặc tả mới là phần đã ổn định của nó; hoặc gần như toàn bộ văn bản cần dịch của bạn nằm trong một ngôn ngữ template chứ không phải trong mã nguồn Python.
Đã có sẵn catalog? Chúng vẫn chạy tốt. _("Hello {name}").format(name=name) và
tr(t"Hello {name}") sinh ra cùng một msgid, nên các bản dịch hiện có sống sót
qua lần chuyển đổi — Chuyển đổi đi hết cả chặng đường ấy.
Catalog được phép nói gì¶
Một bản dịch không thể thay đổi cấu trúc của thông điệp mà nó dịch. Đó là
toàn bộ lời hứa, và mọi phần còn lại của trang này đều theo sau nó. Một bản dịch
có thể đảo thứ tự hoặc lặp lại {name}, và có thể viết lại mọi từ khác quanh
nó. Nó không được phép bỏ mất placeholder, bịa ra một cái mới, thò qua nó để với
vào đối tượng của bạn, hay gắn định dạng của riêng mình.
Thư viện kiểm tra điều đó ở đầu vào — khi catalog được biên dịch — và kiểm tra lại lúc kết xuất, và đó chính là khác biệt giữa một sai sót được tìm thấy trong lúc rà soát và một sai sót được người dùng tìm thấy.
Mới biết đến gettext? Toàn bộ quy trình trong bốn câu
gettext là cách chuẩn để phần mềm được dịch, trong Python và xa hơn
thế nữa. Mã của bạn đánh dấu các chuỗi cần dịch; một trình trích xuất
thu thập chúng vào một tệp mẫu (.pot); người dịch — thường không phải
lập trình viên — điền vào một tệp catalog (.po) cho mỗi ngôn ngữ, rồi
tệp đó được biên dịch thành tệp nhị phân .mo mà ứng dụng của bạn nạp
lúc chạy. Tên quy ước của hàm dịch là _, nên _(t"Hello {name}")
đọc như "dịch câu này". Hướng dẫn nhập môn đi hết
con đường — đánh dấu, trích xuất, dịch, biên dịch, chạy — trong khoảng
năm phút.
Vấn đề nó giải quyết¶
Một f-string đã bị nội suy trước khi bất kỳ thư viện nào nhìn thấy nó —
f"Hello {name}" đã trở thành "Hello Ada", và việc dịch từng mảnh văn bản
quanh một giá trị sẽ phá vỡ ngữ pháp của hầu hết các ngôn ngữ. Một t-string
(PEP 750) giữ tách bạch phần văn bản tĩnh, các giá trị đã được tính, các
biểu thức nguồn, các phép chuyển đổi và các format spec — đúng là cách phân
tách mà một catalog thông điệp cần.
Điều đó thay đổi những gì, so với %(name)s, .format() và
chuỗi $.
Tuy nhiên, không có gì trong gettext hay Babel quy định một t-string trở thành thông điệp như thế nào. Thư viện này đưa ra lựa chọn đó, ghi nó thành một đặc tả có phiên bản, và kèm theo bộ kiểm thử tuân thủ để kiểm chứng.
Các nguyên tắc thiết kế¶
- Dịch thông điệp trọn vẹn, không bao giờ dịch mảnh câu.
- Chỉ chấp nhận tên biến đơn giản như
{name}. - Giữ
!rvà:.2fdưới quyền kiểm soát của ứng dụng, ngoài catalog. - Cho phép người dịch đảo thứ tự và lặp lại các placeholder đã biết, đồng thời ngăn họ với tới thuộc tính hay thêm định dạng.
- Tái sử dụng các tệp POT, PO, MO thông thường, cùng những công cụ vốn đã đọc được chúng.
Và đây là danh sách tương ứng của những gì nó cố tình không đụng tới: nó không bản địa hóa số, tiền tệ hay ngày tháng — hãy định dạng chúng trước, bằng Babel; nó không escape kết quả kết xuất cho HTML, shell hay terminal; và nó không thể phán xét một bản dịch có đúng hay không, chỉ biết các placeholder của bản dịch ấy còn nguyên vẹn hay không.
Cài đặt¶
Python 3.14 trở lên. Phần kết xuất không có phụ thuộc nào — nó chỉ dùng
gettext của thư viện chuẩn và không gì khác.
Trích xuất và kiểm tra catalog chạy qua Babel, nên hãy cài extra đó ở nơi
pybabel chạy, thường là môi trường phát triển hoặc CI chứ không phải image
production:
Đi tiếp đến đâu¶
Bắt đầu ở đây — không đòi hỏi kinh nghiệm gettext:
- Hướng dẫn nhập môn — từ một thư mục trống đến một bản dịch tiếng Nhật chạy được trong năm bước, mọi lệnh đều kèm kết quả thật.
- Vì sao chọn t-string — cùng một thông điệp viết theo
bốn cách, và những gì
%(name)s,.format()và chuỗi$mỗi loại trao cho catalog.
Bắt tay vào dùng — các tài liệu tham chiếu khi làm việc:
- Cẩm nang — API lúc chạy: chọn điểm vào nào, số nhiều, ngôn ngữ theo từng request, chuỗi trì hoãn, và điều gì xảy ra khi một catalog sai.
- Trích xuất — tài liệu tham chiếu
pybabel: cấu hình, tên hàm tùy biến, và cách các công cụ sẵn có kiểm tra những catalog này miễn phí. - Vận hành thực tế — vòng lặp như một đội ngũ vận hành nó: chu kỳ cập nhật, các mục fuzzy, cổng chặn CI, nền tảng dịch thuật, và chuyện đưa bản dịch lên sản phẩm.
- Chuyển đổi — áp dụng thư viện này vào một dự án đã có sẵn catalog, mỗi lần một điểm gọi.
- Dành cho người dịch — một trang duy nhất để đưa cho ai
đó sẽ sửa các tệp
.po.
Hiểu nó — từ lịch sử đến hiện thực:
- Bối cảnh — vì sao thư viện này tồn tại: ba mươi năm gettext, hai PEP, và cuộc thảo luận về thư viện chuẩn khép lại mà không có câu trả lời.
- Cạm bẫy — việc dịch trang này ra ba mươi lăm ngôn ngữ đã thực sự làm hỏng những gì, và công cụ bắt được phân nửa nào.
- Cách hoạt động — từ đối tượng template của PEP 750 đến chuỗi được kết xuất, và các cache khiến việc kiểm tra trở nên rẻ.
Tra cứu — các bản hợp đồng:
Trạng thái¶
| Phiên bản gói | 0.1.0a8 |
| Độ ổn định API | alpha — API Python vẫn có thể thay đổi |
| Đặc tả | v1, kèm bộ kiểm thử tuân thủ |
| Python | 3.14 trở lên; đã kiểm thử trên 3.14, 3.14t (free-threaded) và 3.15 |
| Babel | 2.18 trở lên, và chỉ ở nơi pybabel chạy |
| Phụ thuộc lúc chạy | không có — chỉ gettext của thư viện chuẩn |
| Định dạng catalog | POT, PO và MO thông thường |
| Thay đổi | CHANGELOG |
Một bản alpha. Hợp đồng được giữ nhỏ một cách có chủ đích và đặc tả là phần ổn định của nó; API Python vẫn có thể thay đổi. Trước một bản phát hành ổn định, dự án cần thêm fixture cho nhiều ngôn ngữ hơn, theo dõi hiệu năng bền bỉ, đánh giá API từ những người dùng gettext và Babel nghiêm túc, và kiểm thử tương thích trên mọi bản Python và Babel được hỗ trợ.
Issue và pull request đều được chào đón — bản alpha chính là lúc giao diện còn đáng để tranh luận.
Tham gia cộng đồng¶
- Chọn một good first issue cho một đóng góp có phạm vi gọn.
- Đặt câu hỏi sử dụng tại Q&A Discussions.
- Mang quy trình gettext trong production và ý tưởng API đến Ideas Discussions.
- Đọc hướng dẫn đóng góp trước khi mở pull request.