Python, một ngôn ngữ lập trình phổ biến, hỗ trợ mạnh mẽ việc xử lý văn bản. Điều này bao gồm cả việc sử dụng hệ thống Unicode, một tiêu chuẩn mã hóa ký tự quan trọng. Việc hiểu rõ về cách Python xử lý Unicode, các cách mã hóa và giải mã ký tự là nền tảng thiết yếu cho việc thao tác dữ liệu dạng văn bản một cách chính xác và hiệu quả. Để tìm hiểu chi tiết hơn về vai trò của Unicode trong Python, cùng những khía cạnh liên quan, bạn hãy đọc tiếp bài viết này.
Hệ thống Unicode trong Python
Trong quá trình xây dựng phần mềm, chúng ta thường cần hiển thị thông báo hoặc xuất dữ liệu ra nhiều ngôn ngữ khác nhau, ví dụ như tiếng Anh, tiếng Pháp, tiếng Nhật, tiếng Do Thái, hay tiếng Hindi. Để đáp ứng yêu cầu này, Python sử dụng Unicode cho kiểu dữ liệu chuỗi (string). Điều này giúp chương trình có thể làm việc với hầu hết các ký tự trên thế giới.
Vậy Unicode là gì? Chúng ta có thể hiểu đơn giản:
Unicode là một tiêu chuẩn quốc tế dùng để mã hóa các ký tự, biểu tượng, và chữ viết từ hầu hết các ngôn ngữ khác nhau trên thế giới. Nó đảm bảo rằng mỗi ký tự được gán một số duy nhất, giúp các máy tính hiểu và hiển thị chúng một cách chính xác.
Để dễ hình dung, hãy dưới đây là một vài khái niệm:
- Đơn vị mã (Code Unit) và Byte: Dãy các điểm mã này cần được biểu diễn trong bộ nhớ bằng một tập các đơn vị mã. Sau đó, các đơn vị mã sẽ được chuyển đổi thành các byte 8 bit để máy tính có thể lưu trữ và xử lý.
- Ký tự (Character): Là đơn vị nhỏ nhất trong một văn bản. Các chữ cái như ‘A’, ‘B’, ‘C’, hay các chữ cái có dấu như ‘À’, ‘È’, ‘Í’, đều là các ký tự riêng biệt.
- Chuỗi Unicode (Unicode String): Là một dãy các “điểm mã” (code point). Điểm mã là các số nguyên trong phạm vi từ 0 đến 1.114.111 (hệ thập phân). Mỗi điểm mã này tương ứng với một ký tự Unicode.
Mã hóa ký tự trong Python
Mã hóa ký tự là một bộ quy tắc định nghĩa cách chuyển đổi một chuỗi Unicode (dãy các điểm mã) thành một dãy các byte. Quy tắc này giúp máy tính biết cách diễn giải dữ liệu đã lưu trữ để hiển thị đúng các ký tự tương ứng.
Có nhiều bảng mã hóa ký tự, nhưng dưới đây là 3 loại phổ biến mà bạn thường gặp khi làm việc với Python và Unicode:
- UTF-32: (Unicode Transformation Format – 32-bit) UTF-32 sử dụng đúng 4 byte để mã hóa một ký tự Unicode. Phương pháp này có ưu điểm là đơn giản, việc tìm đúng byte tương ứng cho từng ký tự rất dễ dàng, nhưng lại không tiết kiệm bộ nhớ bằng UTF-8.
- UTF-8: (Unicode Transformation Format – 8-bit) Đây là bảng mã hóa thông dụng nhất trên internet. UTF-8 sử dụng từ 1 đến 4 byte để mã hóa một ký tự Unicode, tùy thuộc vào giá trị điểm mã. UTF-8 có ưu điểm là tiết kiệm bộ nhớ cho các ký tự ASCII (các ký tự thường dùng trong tiếng Anh) và tương thích tốt với các hệ thống cũ.
- UTF-16: (Unicode Transformation Format – 16-bit) UTF-16 sử dụng 2 hoặc 4 byte để mã hóa một ký tự Unicode. UTF-16 được sử dụng rộng rãi trong các hệ điều hành Windows và Java.
Khả năng hỗ trợ Unicode của Python
Từ phiên bản Python 3.0 trở đi, ngôn ngữ này đã tích hợp sẵn khả năng hỗ trợ Unicode. Kiểu dữ liệu str (chuỗi) trong Python chứa các ký tự Unicode, nghĩa là bất kỳ chuỗi nào được tạo bằng cách sử dụng dấu nháy đơn, dấu nháy đôi, hoặc dấu nháy ba đều được lưu trữ dưới dạng Unicode. Điều này đồng nghĩa với việc, bạn không cần phải lo lắng về việc cài đặt thêm thư viện hay tùy chỉnh gì để có thể dùng được Unicode. Thêm nữa, mã hóa mặc định cho mã nguồn Python là UTF-8.
Vì thế, một chuỗi ký tự có thể chứa trực tiếp một ký tự Unicode (ví dụ, “3/4
“), hoặc giá trị Unicode của ký tự đó (ví dụ, \u00BE
).
Ví dụ 1
chuoi1 = "Bản quyền ©"
print(chuoi1)
chuoi2 = "\u00A9"
print(chuoi2)
chuoi3 = "Tiếng Việt có dấu ừ, ế, à..."
print (chuoi3)
Kết quả khi chạy đoạn code trên sẽ là:
Bản quyền ©
©
Tiếng Việt có dấu ừ, ế, à…
Ví dụ 2
Trong ví dụ sau, chuỗi ‘10
‘ được lưu trữ bằng cách sử dụng các giá trị Unicode tương ứng của ký tự ‘1
‘ và ‘0
‘, lần lượt là \u0031
và \u0030
.
var = "\u0031\u0030"
print (var)
Khi chạy đoạn code này, kết quả sẽ là:
10
Chuỗi (string) hiển thị văn bản ở dạng mà con người có thể đọc được. Trong khi đó, bytes lưu trữ các ký tự dưới dạng dữ liệu nhị phân (dạng số 0 và 1 mà máy tính có thể hiểu được).
- Giải mã (decoding): Là quá trình ngược lại, chuyển đổi dữ liệu từ các byte thành các ký tự hoặc biểu tượng dễ đọc đối với con người. Cũng tương tự việc giải mã Morse để đọc được nội dung gốc.
- Mã hóa (encoding): Là quá trình chuyển đổi dữ liệu từ một chuỗi ký tự (dạng dễ đọc với người) thành một dãy các byte (dạng máy tính hiểu được). Tưởng tượng việc mã hóa giống như quá trình biến một văn bản thông thường sang mã Morse.
Ví dụ 3
Để minh họa rõ hơn cách Unicode hoạt động trong Python, hãy xem xét một ví dụ cụ thể. Trong ví dụ dưới đây, chúng ta có một biến chuỗi (string) chứa các ký tự ASCII. Cần lưu ý rằng, bảng mã ASCII là một tập con của bảng mã Unicode. Chúng ta sẽ sử dụng phương thức encode()
để chuyển đổi chuỗi ký tự này thành một đối tượng kiểu bytes.
chuoi = "Xin chào"
bytes_object = chuoi.encode('utf-8')
print (bytes_object)
chuoi_goc = bytes_object.decode('utf-8')
print (chuoi_goc)
Khi thực thi đoạn code trên, kết quả sẽ hiển thị như sau:
b’Xin ch\xc3\xa0o’
Xin chào
Ví dụ 4
Trong đoạn code sau, biểu tượng đồng Việt Nam (₫) được lưu trữ trong biến bằng cách sử dụng giá trị Unicode tương ứng. Sau đó, chúng ta chuyển đổi chuỗi thành bytes và ngược lại chuyển từ bytes thành chuỗi.
tien_viet = "\u20AB" # Giá trị Unicode cho ký hiệu ₫
print(tien_viet)
sang_bytes = tien_viet.encode('utf-8')
print(sang_bytes)
tro_lai_chuoi = sang_bytes.decode('utf-8')
print(tro_lai_chuoi)
Khi bạn thực thi đoạn code trên, bạn sẽ thấy kết quả như sau:
₫
b’\xe2\x82\xab’
₫
Lời kết
Như vậy, chúng ta vừa cùng nhau khám phá chi tiết về hệ thống Unicode trong Python, cách mã hóa ký tự, cũng như khả năng hỗ trợ Unicode tuyệt vời của ngôn ngữ này thông qua các ví dụ minh họa cụ thể. Hy vọng rằng, những kiến thức này sẽ hữu ích và giúp bạn hiểu rõ hơn về cách Python xử lý văn bản, đặc biệt là với các ngôn ngữ đa dạng trên toàn thế giới.