PEP 686 - Từ Python 3.15, chế độ UTF-8 được đặt làm mặc định
- UTF-8 đang dần trở thành chuẩn mã hóa văn bản trên thực tế
- Mã hóa mặc định của tệp nguồn Python là UTF-8
- JSON, TOML, YAML sử dụng UTF-8
- Hầu hết trình soạn thảo văn bản như Visual Studio Code, Windows Notepad đều dùng UTF-8 theo mặc định
- Phần lớn website và dữ liệu văn bản trên Internet sử dụng UTF-8
- Nhiều ngôn ngữ lập trình phổ biến khác như Node.js, Go, Rust, Java cũng dùng UTF-8 theo mặc định
- Việc chuyển mã hóa mặc định sang UTF-8 giúp Python dễ tương tác hơn với các ngôn ngữ khác
- Nhiều nhà phát triển Python trên Unix quên mất rằng mã hóa mặc định khác nhau tùy theo nền tảng
- Khi đọc các tệp văn bản được mã hóa bằng UTF-8 (JSON, TOML, Markdown, tệp nguồn Python, v.v.), họ không chỉ định
encoding="utf-8"
- Nhiều lỗi phát sinh do mã hóa mặc định không nhất quán
Những thay đổi chính của PEP 686
- Từ Python 3.15, chế độ UTF-8 sẽ được bật mặc định
- Người dùng vẫn có thể tắt chế độ UTF-8 bằng cách đặt
PYTHONUTF8=0 hoặc -X utf8=0
- Thêm
locale.getencoding()
- API để lấy mã hóa locale bất kể chế độ UTF-8
- Nếu tùy chọn
warn_default_encoding được chỉ định, locale.getpreferredencoding() sẽ phát sinh EncodingWarning giống như open() (tham khảo PEP 597)
- Điều chỉnh tùy chọn
encoding="locale"
TextIOWrapper phải sử dụng mã hóa locale ngay cả trong chế độ UTF-8 nếu encoding="locale" được chỉ định
Tính tương thích ngược
- Hầu hết hệ thống Unix sử dụng locale UTF-8, và Python bật chế độ UTF-8 khi locale là C hoặc POSIX, vì vậy thay đổi này chủ yếu ảnh hưởng đến người dùng Windows
- Nếu chương trình Python phụ thuộc vào mã hóa mặc định, thay đổi này có thể gây ra
UnicodeError, lỗi hiển thị ký tự, hoặc hỏng dữ liệu âm thầm
- Hướng dẫn để xử lý các vấn đề tương thích ngược:
- Tắt chế độ UTF-8
- Dùng
EncodingWarning (PEP 597) để tìm mọi vị trí bị ảnh hưởng bởi chế độ UTF-8
- Nếu bỏ qua tùy chọn
encoding, hãy cân nhắc dùng encoding="utf-8" hoặc encoding="locale"
- Nếu đang dùng
locale.getpreferredencoding(), hãy cân nhắc dùng "utf-8" hoặc locale.getencoding()
- Kiểm thử ứng dụng với chế độ UTF-8
Ý kiến của GN⁺
- PEP này nhằm thống nhất mã hóa mặc định của Python về UTF-8 để tăng khả năng tương tác với các ngôn ngữ và hệ thống khác. Điều này sẽ giúp Python được sử dụng trơn tru hơn trong môi trường phát triển toàn cầu
- Tuy nhiên, thay đổi này có thể ảnh hưởng đến tính tương thích ngược của các chương trình Python hiện có. Đặc biệt, cần chú ý với các chương trình chạy trong môi trường Windows
- Các nhà phát triển nên tận dụng
EncodingWarning để xác định những phần bị ảnh hưởng, và ứng phó bằng cách chỉ định rõ ràng tùy chọn encoding
- Về dài hạn, thay đổi này được kỳ vọng sẽ mang lại tác động tích cực cho hệ sinh thái Python. Tuy nhiên, trong ngắn hạn, một số dự án có thể phát sinh chi phí di chuyển
- Các nhà phát triển nên cân nhắc thay đổi này khi lập kế hoạch nâng cấp lên Python 3.15, và nếu cần thì áp dụng các biện pháp phù hợp để đảm bảo tương thích ngược
1 bình luận
Ý kiến trên Hacker News
init.d. Các script khởi chạy Java chạy bằng quyền root đã dùng mã hóa khác với người dùng thông thường, gây ra sự cốPython 2 không bị ràng buộc bởi charset nên lúc nào cũng chạy ổn, nhưng các cải tiến của Python 3 còn hơn cả cải tiến đơn thuần
Cách phân biệt script Python 3 với script Python 2:
"utf-8"thì là Python 3C.UTF-8thì là Python 3Thay đổi này rất đáng hoan nghênh và có vẻ sẽ "cải thiện" Python 3
Tôi đã nghĩ đây là mặc định từ Python 3 rồi
Tôi không biết là Java đã chuyển từ UTF-16 sang UTF-8
Tôi không rõ mã hóa nội bộ của CPython có phải là UTF-8 hay không
Chuỗi trong Python có thể được đánh chỉ mục, nhưng truy cập ngẫu nhiên là hiếm, nên có lẽ tốt hơn là lập chỉ mục trì hoãn khi cần
Nếu chỉ di chuyển tới lui từng ký tự một thì không cần chỉ mục
Vì vậy có vẻ nội bộ hoàn toàn có thể biểu diễn bằng UTF-8
Tại sao không phải là
utf-8-sig? Nó hữu ích vì có thể xử lý BOM một cách tùy chọnNói về UTF-8, Linux framebuffer lẽ ra từ lâu đã phải có hỗ trợ UTF-8 đúng nghĩa
GNU Hurd đã có một 'terminal console' tốt hơn hỗ trợ UTF-8 từ khoảng năm 2007
Mãi đến năm 2024 mới có thay đổi kiểu này
Thay đổi tốt. Giờ chỉ còn JS là cần chuyển sang UTF-8, nhưng vì phải tương thích với mã viết từ năm 1995 nên rất khó cải thiện