Một trong những kiểu chuỗi dựng sẵn ít được biết đến trong Python là bytes, một dãy bất biến (immutable) các số nguyên. Mỗi số nguyên biểu diễn một byte dữ liệu. Dữ liệu thường được truyền qua mạng và giữa các chương trình ở dạng bytes. Bytes không thể đọc trực tiếp bằng mắt người, nên chúng ta thường cần chuyển chúng thành chuỗi trong các chương trình Python.
Hướng dẫn này khám phá các kỹ thuật chuyển bytes thành chuỗi trong Python. Nếu bạn quan tâm đến thao tác ngược lại, hãy xem hướng dẫn của tôi về cách chuyển chuỗi thành bytes trong Python.
Hãy bắt đầu với câu trả lời ngắn gọn cho những bạn cần nhanh.
Câu trả lời ngắn: Cách chuyển Bytes thành String trong Python
Công cụ chính để chuyển bytes thành chuỗi trong Python là phương thức .decode():
data =b"\xc3\xa9clair"
text = data.decode(encoding="utf-8")print(text)Được hỗ trợ bởi
Phương thức .decode() trả về một chuỗi biểu diễn đối tượng bytes. Trong ví dụ này, sử dụng giải mã UTF-8. UTF-8 là bảng mã mặc định, nên không bắt buộc trong ví dụ trên, nhưng chúng ta cũng có thể dùng các bảng mã khác.
Tìm hiểu về Bytes và Strings trong Python
Python có cấu trúc dữ liệu dựng sẵn bytes, là một dãy bất biến các số nguyên trong khoảng từ 0 đến 255. Một số nguyên trong khoảng 256 giá trị này có thể được biểu diễn bằng tám bit dữ liệu, tức một byte. Do đó, mỗi phần tử trong một đối tượng bytes là một số nguyên đại diện cho một byte.
Hãy dùng hàm tạo bytes() để tạo một đối tượng bytes từ một danh sách:
data =bytes([68,97,116,97,67,97,109,112])print(type(data))Được hỗ trợ bởi
Traceback (most recent call last):
...
data[0] = 100
~~~~^^^
TypeError: 'bytes' object does not support item assignmentĐược hỗ trợ bởi
Python sẽ phát sinh TypeError khi chúng ta cố thay đổi một giá trị trong dãy này. Hãy xác nhận rằng một đối tượng bytes chỉ có thể chứa các số nguyên từ 0 đến 255:
Traceback (most recent call last):
...
data = bytes([254, 255, 256])
^^^^^^^^^^^^^^^^^^^^^^
ValueError: bytes must be in range(0, 256)Được hỗ trợ bởi
ValueError cho biết một số nguyên biểu diễn byte phải là phần tử của range(0, 256). Điểm cuối của range bị loại trừ, đúng theo quy ước về dãy số trong Python.
Chúng ta có thể hiển thị đối tượng bytes bằng print():
data =bytes([68,97,116,97,67,97,109,112])print(data)Được hỗ trợ bởi
Biểu diễn này cho thấy đối tượng bytes được thể hiện bằng các ký tự. Python hiển thị các số nguyên bằng những ký tự ASCII tương ứng với các giá trị đó. Tiền tố b trước các ký tự trong dấu nháy cho biết đây là một đối tượng bytes.
Chúng ta cũng có thể tạo một đối tượng bytes bằng literal bytes trực tiếp:
Đối tượng được hiển thị bằng ký tự, nhưng các phần tử của nó là số nguyên.
Tuy nhiên, các đối tượng bytes chỉ có thể đọc được bằng mắt người khi dùng các số nguyên tương ứng với ký tự ASCII có thể in. Vì ASCII là bảng mã 7-bit, nó có 128 mã, nhưng chỉ 95 ký tự ASCII là có thể in.
Các số nguyên từ 0 đến 127 không có ký tự ASCII có thể in và các số nguyên từ 128 đến 255 sẽ được hiển thị dưới dạng số thập lục phân:
data =bytes([0,68,97,116,97,67,97,109,112,200])print(data)Được hỗ trợ bởi
Phần tử đầu tiên trong danh sách giờ là 0, không phải ký tự có thể in trong ASCII. Đối tượng bytes hiển thị số nguyên này là \x00, dạng thập lục phân của 0. Số nguyên cuối cùng là 200, nằm ngoài phạm vi ASCII nhưng vẫn trong phạm vi số nguyên có thể dùng trong bytes. Python hiển thị số nguyên này là \xc8, tức 200 ở hệ thập lục phân.
Cấu trúc dữ liệu bytes và chuỗi có những điểm chung. Cả hai đều là các dãy bất biến, nhưng bytes chứa số nguyên, còn chuỗi chứa ký tự:
data =bytes([68,97,116,97,67,97,109,112])print(data[0])
text ="DataCamp"print(text[0])Được hỗ trợ bởi
Bytes được dùng để truyền dữ liệu qua mạng và giữa các giao diện khác nhau. Phần tiếp theo của bài viết sẽ khám phá cách chuyển bytes thành chuỗi.
Chuyển Bytes thành Chuỗi: Phương thức .decode()
Một đối tượng bytes trong Python chỉ có thể đọc được bằng mắt người khi nó chứa các ký tự ASCII đọc được. Trong hầu hết ứng dụng, các ký tự này là không đủ. Chúng ta có thể chuyển một đối tượng bytes thành chuỗi bằng phương thức .decode():
data =bytes([68,97,116,97,67,97,109,112])
text = data.decode()print(text)print(type(text))Được hỗ trợ bởi
Tuy nhiên, có nhiều bảng mã khác nhau để chuyển đổi giữa bytes và chuỗi. Các số nguyên trong ví dụ trên biểu diễn các ký tự ASCII có thể in. Tuy nhiên, bảng mã mặc định được dùng khi không truyền đối số cho .decode() là UTF-8 chứ không phải ASCII. UTF-8 là bảng mã được dùng rộng rãi nhất cho các ký tự Unicode.
128 mã UTF-8 đầu tiên trùng với mã ASCII, đó là lý do đối tượng bytes trên được giải mã thành chuỗi "DataCamp" trong ví dụ.
Tuy nhiên, Unicode chứa gần 150.000 ký tự. UTF-8 mã hóa tất cả các ký tự không phải ASCII trong Unicode bằng hai byte trở lên.
Hãy tạo một đối tượng bytes mới và giải mã nó:
data =bytes([195,169])print(data)
text = data.decode()print(text)Được hỗ trợ bởi
Đối tượng bytes chứa hai byte: các số nguyên 195 và 169. Python hiển thị dạng thập lục phân của các byte này. Tuy nhiên, .decode() trả về một chuỗi bằng cách giải mã đối tượng bytes theo bảng mã UTF-8. Cặp byte b'\xc3\xa9' biểu diễn chữ e có dấu sắc, é.
Phương thức .decode() nhận một đối số tùy chọn để chỉ định bảng mã:
UTF-8 là bảng mã mặc định, nhưng có thể dùng các bảng mã khác. Chúng ta cũng có thể chuyển một chuỗi thành đối tượng bytes bằng phương thức chuỗi .encode() với nhiều bảng mã khác nhau:
text ="éclair"
data = text.encode("utf-8")print(data)
data = text.encode("utf-16")print(data)Được hỗ trợ bởi
b'\xc3\xa9clair'
b'\xff\xfe\xe9\x00c\x00l\x00a\x00i\x00r\x00'Được hỗ trợ bởi
Cùng một chuỗi có thể được chuyển thành các đối tượng bytes khác nhau tùy theo bảng mã chúng ta dùng.
Lỗi mã hóa
Việc lựa chọn bảng mã có thể dẫn đến lỗi nếu dùng bảng mã khác nhau khi chuyển đổi giữa bytes và chuỗi. Hãy dùng ví dụ với chuỗi "éclair" được mã hóa sang bytes bằng UTF-8:
text ="éclair"
data = text.encode("utf-8")print(data)Được hỗ trợ bởi
Traceback (most recent call last):
...
text = data.decode("ascii")
^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)Được hỗ trợ bởi
Tuy nhiên, chúng ta có thể truyền đối số tùy chọn errors để xử lý lỗi. Giá trị mặc định của tham số errors là "strict", sẽ phát sinh lỗi khi gặp ký tự không hợp lệ.
Phương thức .decode() có thể được gọi với errors="ignore" để bỏ qua tất cả ký tự không hợp lệ:
text = data.decode("ascii", errors="ignore")print(text)Được hỗ trợ bởi
Kết quả này cho thấy các ký tự bị thiếu trong chuỗi. Cách xử lý lỗi phụ thuộc vào ứng dụng.
Chuyển Bytes thành Chuỗi bằng str()
Phương thức .decode() là con đường chính để chuyển bytes thành chuỗi. Tuy nhiên, cũng có thể dùng trực tiếp hàm tạo str(). Dùng str() trên một đối tượng bytes sẽ tạo chuỗi biểu diễn các byte thô:
data =b'\xc3\xa9clair'
text =str(data)print(text)print(type(text))Được hỗ trợ bởi
Mô-đun codecs trong thư viện chuẩn của Python cung cấp giao diện để mã hóa và giải mã dữ liệu. Mô-đun này cũng cung cấp hàm .decode() có thể dùng để chuyển bytes của Python thành chuỗi:
import codecs
data =b'\xc3\xa9clair'
text = codecs.decode(data, encoding='utf-8')print(text)Được hỗ trợ bởi
Các kỹ thuật chuyển đổi thay thế này không phải là phương thức của kiểu bytes mà là các hàm yêu cầu truyền đối tượng bytes làm đối số.
Kết luận
Dữ liệu thường được truyền ở dạng bytes, và nhiều ứng dụng Python cần chuyển đổi giữa bytes và chuỗi. Một đối tượng bytes là dãy bất biến các byte, có thể chuyển thành string bằng một trong nhiều bảng mã ký tự.
Con đường chính để chuyển bytes của Python thành chuỗi là phương thức .decode(), cho phép người dùng chọn bảng mã và chiến lược xử lý lỗi.
Bạn có thể tiếp tục học Python với các hướng dẫn và khóa học sau:
Tôi học Vật lý và Toán ở bậc đại học tại Đại học Malta. Sau đó, tôi chuyển đến London và lấy bằng Tiến sĩ Vật lý tại Imperial College. Tôi nghiên cứu các kỹ thuật quang học mới để chụp ảnh võng mạc người. Hiện nay, tôi tập trung vào việc viết về Python, truyền đạt về Python và giảng dạy Python.
Một trong những kiểu chuỗi dựng sẵn ít được biết đến trong Python là bytes, một dãy bất biến (immutable) các số nguyên. Mỗi số nguyên biểu diễn một byte dữ liệu. Dữ liệu thường được truyền qua mạng và giữa các chương trình ở dạng bytes. Bytes không thể đọc trực tiếp bằng mắt người, nên chúng ta thường cần chuyển chúng thành chuỗi trong các chương trình Python.
Hướng dẫn này khám phá các kỹ thuật chuyển bytes thành chuỗi trong Python. Nếu bạn quan tâm đến thao tác ngược lại, hãy xem hướng dẫn của tôi về cách chuyển chuỗi thành bytes trong Python.
Hãy bắt đầu với câu trả lời ngắn gọn cho những bạn cần nhanh.
Câu trả lời ngắn: Cách chuyển Bytes thành String trong Python
Công cụ chính để chuyển bytes thành chuỗi trong Python là phương thức
.decode():Phương thức
.decode()trả về một chuỗi biểu diễn đối tượngbytes. Trong ví dụ này, sử dụng giải mã UTF-8. UTF-8 là bảng mã mặc định, nên không bắt buộc trong ví dụ trên, nhưng chúng ta cũng có thể dùng các bảng mã khác.Tìm hiểu về Bytes và Strings trong Python
Python có cấu trúc dữ liệu dựng sẵn
bytes, là một dãy bất biến các số nguyên trong khoảng từ 0 đến 255. Một số nguyên trong khoảng 256 giá trị này có thể được biểu diễn bằng tám bit dữ liệu, tức một byte. Do đó, mỗi phần tử trong một đối tượngbyteslà một số nguyên đại diện cho một byte.Hãy dùng hàm tạo
bytes()để tạo một đối tượngbytestừ một danh sách:Dãy số nguyên này là bất biến:
Python sẽ phát sinh
TypeErrorkhi chúng ta cố thay đổi một giá trị trong dãy này. Hãy xác nhận rằng một đối tượngbyteschỉ có thể chứa các số nguyên từ 0 đến 255:ValueErrorcho biết một số nguyên biểu diễn byte phải là phần tử củarange(0, 256). Điểm cuối của range bị loại trừ, đúng theo quy ước về dãy số trong Python.Chúng ta có thể hiển thị đối tượng bytes bằng
print():Biểu diễn này cho thấy đối tượng
bytesđược thể hiện bằng các ký tự. Python hiển thị các số nguyên bằng những ký tự ASCII tương ứng với các giá trị đó. Tiền tố b trước các ký tự trong dấu nháy cho biết đây là một đối tượngbytes.Chúng ta cũng có thể tạo một đối tượng
bytesbằng literal bytes trực tiếp:Đối tượng được hiển thị bằng ký tự, nhưng các phần tử của nó là số nguyên.
Tuy nhiên, các đối tượng
byteschỉ có thể đọc được bằng mắt người khi dùng các số nguyên tương ứng với ký tự ASCII có thể in. Vì ASCII là bảng mã 7-bit, nó có 128 mã, nhưng chỉ 95 ký tự ASCII là có thể in.Các số nguyên từ 0 đến 127 không có ký tự ASCII có thể in và các số nguyên từ 128 đến 255 sẽ được hiển thị dưới dạng số thập lục phân:
Phần tử đầu tiên trong danh sách giờ là 0, không phải ký tự có thể in trong ASCII. Đối tượng
byteshiển thị số nguyên này là\x00, dạng thập lục phân của 0. Số nguyên cuối cùng là 200, nằm ngoài phạm vi ASCII nhưng vẫn trong phạm vi số nguyên có thể dùng trong bytes. Python hiển thị số nguyên này là\xc8, tức 200 ở hệ thập lục phân.Cấu trúc dữ liệu
bytesvà chuỗi có những điểm chung. Cả hai đều là các dãy bất biến, nhưngbyteschứa số nguyên, còn chuỗi chứa ký tự:Bytes được dùng để truyền dữ liệu qua mạng và giữa các giao diện khác nhau. Phần tiếp theo của bài viết sẽ khám phá cách chuyển bytes thành chuỗi.
Chuyển Bytes thành Chuỗi: Phương thức
.decode()Một đối tượng
bytestrong Python chỉ có thể đọc được bằng mắt người khi nó chứa các ký tự ASCII đọc được. Trong hầu hết ứng dụng, các ký tự này là không đủ. Chúng ta có thể chuyển một đối tượngbytesthành chuỗi bằng phương thức.decode():Tuy nhiên, có nhiều bảng mã khác nhau để chuyển đổi giữa bytes và chuỗi. Các số nguyên trong ví dụ trên biểu diễn các ký tự ASCII có thể in. Tuy nhiên, bảng mã mặc định được dùng khi không truyền đối số cho
.decode()là UTF-8 chứ không phải ASCII. UTF-8 là bảng mã được dùng rộng rãi nhất cho các ký tự Unicode.128 mã UTF-8 đầu tiên trùng với mã ASCII, đó là lý do đối tượng bytes trên được giải mã thành chuỗi
"DataCamp"trong ví dụ.Tuy nhiên, Unicode chứa gần 150.000 ký tự. UTF-8 mã hóa tất cả các ký tự không phải ASCII trong Unicode bằng hai byte trở lên.
Hãy tạo một đối tượng
bytesmới và giải mã nó:Đối tượng
byteschứa hai byte: các số nguyên 195 và 169. Python hiển thị dạng thập lục phân của các byte này. Tuy nhiên,.decode()trả về một chuỗi bằng cách giải mã đối tượngbytestheo bảng mã UTF-8. Cặp byteb'\xc3\xa9'biểu diễn chữ e có dấu sắc, é.Phương thức
.decode()nhận một đối số tùy chọn để chỉ định bảng mã:UTF-8 là bảng mã mặc định, nhưng có thể dùng các bảng mã khác. Chúng ta cũng có thể chuyển một chuỗi thành đối tượng
bytesbằng phương thức chuỗi.encode()với nhiều bảng mã khác nhau:Cùng một chuỗi có thể được chuyển thành các đối tượng
byteskhác nhau tùy theo bảng mã chúng ta dùng.Lỗi mã hóa
Việc lựa chọn bảng mã có thể dẫn đến lỗi nếu dùng bảng mã khác nhau khi chuyển đổi giữa bytes và chuỗi. Hãy dùng ví dụ với chuỗi
"éclair"được mã hóa sang bytes bằng UTF-8:Dãy byte này biểu diễn các ký tự theo bảng mã UTF-8. Phương thức
.decode()sẽ phát sinh lỗi nếu chúng ta dùng sai bảng mã:Tuy nhiên, chúng ta có thể truyền đối số tùy chọn
errorsđể xử lý lỗi. Giá trị mặc định của tham sốerrorslà"strict", sẽ phát sinh lỗi khi gặp ký tự không hợp lệ.Phương thức
.decode()có thể được gọi vớierrors="ignore"để bỏ qua tất cả ký tự không hợp lệ:Ký tự đầu tiên trong chuỗi gốc là é, không phải ký tự ASCII. Do đó,
.decode()trả về một chuỗi thiếu ký tự đầu tiên.Một lựa chọn khác là gọi
.decode()vớierrors="replace", thay thế các byte không hợp lệ bằng �:Kết quả này cho thấy các ký tự bị thiếu trong chuỗi. Cách xử lý lỗi phụ thuộc vào ứng dụng.
Chuyển Bytes thành Chuỗi bằng
str()Phương thức
.decode()là con đường chính để chuyển bytes thành chuỗi. Tuy nhiên, cũng có thể dùng trực tiếp hàm tạostr(). Dùngstr()trên một đối tượngbytessẽ tạo chuỗi biểu diễn các byte thô:Tuy nhiên, hàm tạo
str()cũng nhận đối sốencoding, cho phép chúng ta tạo chuỗi dựa trên một bảng mã cụ thể:Chuyển Bytes thành Chuỗi với codecs.decode()
Mô-đun
codecstrong thư viện chuẩn của Python cung cấp giao diện để mã hóa và giải mã dữ liệu. Mô-đun này cũng cung cấp hàm.decode()có thể dùng để chuyển bytes của Python thành chuỗi:Các kỹ thuật chuyển đổi thay thế này không phải là phương thức của kiểu
bytesmà là các hàm yêu cầu truyền đối tượngbyteslàm đối số.Kết luận
Dữ liệu thường được truyền ở dạng bytes, và nhiều ứng dụng Python cần chuyển đổi giữa bytes và chuỗi. Một đối tượng
byteslà dãy bất biến các byte, có thể chuyển thànhstringbằng một trong nhiều bảng mã ký tự.Con đường chính để chuyển bytes của Python thành chuỗi là phương thức
.decode(), cho phép người dùng chọn bảng mã và chiến lược xử lý lỗi.Bạn có thể tiếp tục học Python với các hướng dẫn và khóa học sau: