Chuyển đến nội dung chính

Cách chuyển đổi String thành Bytes trong Python

Trong Python, hãy dùng phương thức .encode() trên một chuỗi để chuyển nó thành bytes, có thể chỉ định bảng mã mong muốn (mặc định là UTF-8).
· 7 phút đọc

Khám phá cùng AI

Chuỗi biểu diễn văn bản có thể đọc được bởi con người và là một trong những kiểu dữ liệu cơ bản, quan trọng nhất trong lập trình. Tuy nhiên, mỗi ký tự trong một chuỗi văn bản được biểu diễn bằng một hoặc nhiều byte dữ liệu nhị phân. Các ứng dụng như thao tác nhập/xuất và truyền dữ liệu yêu cầu chuyển đổi chuỗi sang bytes bằng một bảng mã cụ thể.

Hướng dẫn này khám phá các kỹ thuật chuyển đổi chuỗi thành bytes 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 bytes thành chuỗi trong Python.

Trước khi đi vào chi tiết, hãy bắt đầu với câu trả lời ngắn gọn dành cho những bạn đang vội.

Câu trả lời ngắn: Cách chuyển String thành Bytes trong Python

Python giúp chuyển một chuỗi thành bytes rất đơn giản bằng phương thức dựng sẵn .encode():

my_string = "Hello, world!"
bytes_representation = my_string.encode(encoding="utf-8")  
# Optional: Specify the desired encoding (UTF-8 is the default)

print(bytes_representation)
# Output: b'Hello, world!'

Phương thức .encode() trả về một đối tượng bytes mới biểu diễn phiên bản đã mã hóa của chuỗi gốc. Mặc định, nó dùng mã hóa UTF-8, nhưng bạn có thể chỉ định bảng mã khác như 'ascii' hoặc 'latin-1' nếu cần.

Hãy cùng tìm hiểu chi tiết hơn về quy trình chuyển đổi này.

Tìm hiểu về Strings và Bytes trong Python

Hai trong số các kiểu dữ liệu dựng sẵn cốt lõi trong Python là str và bytes. Những kiểu dữ liệu này có một số điểm chung nhưng cũng có khác biệt then chốt.

Cả str và bytes đều là các dãy bất biến, nghĩa là chúng ta không thể sửa đổi phần tử của chúng sau khi tạo. Chuỗi là một dãy bất biến các ký tự, trong khi một đối tượng bytes là một dãy bất biến các số nguyên trong khoảng từ 0 đến 255. Khoảng số nguyên này có thể được biểu diễn bằng 8 bit, tức là một byte. Do đó, một đối tượng bytes là một dãy các byte.

Mã hóa ký tự ASCII

Trước hết, hãy xét các ký tự ASCII. ASCII (American Standard Code for Information Interchange) là một bảng mã ký tự chỉ chứa 128 ký tự. Vì vậy, bất kỳ ký tự ASCII nào cũng có thể được biểu diễn bằng bảy bit, ít hơn một byte.

Chúng ta có thể tạo một đối tượng bytes bằng cách thêm b phía trước dấu nháy đơn, kép hoặc ba mà ta thường dùng cho chuỗi:

word_as_bytes = b"Python"
print(word_as_bytes)
print(type(word_as_bytes))
b'Python'
<class 'bytes'>

Mặc dù mã hiển thị các ký tự tạo thành Python, mỗi phần tử trong đối tượng bytes là một số nguyên từ 0 đến 255:

print(word_as_bytes[0])
print(list(word_as_bytes))
80
[80, 121, 116, 104, 111, 110]

Phần tử đầu tiên của word_as_bytes là số nguyên 80, đây là mã ASCII cho chữ hoa P:

print(chr(80))
P

Khi ép word_as_bytes thành danh sách, danh sách sẽ chứa các số nguyên đại diện cho từng byte. Các số nguyên này là mã ASCII cho các chữ cái trong từ Python.

Tuy nhiên, bộ ký tự ASCII là có giới hạn.

Mã hóa ký tự UTF-8

Bảng mã ký tự phổ biến nhất là UTF-8, một dạng mã hóa Unicode theo đơn vị 8 bit. 128 ký tự ASCII được biểu diễn bởi cùng các số nguyên trong UTF-8, nhưng những ký tự khác cũng có thể được biểu diễn bằng hai hoặc nhiều byte cho mỗi ký tự.

Hãy tạo một đối tượng bytes dùng ký tự không thuộc ASCII. Chúng ta sẽ cần dùng hàm tạo bytes():

word_as_bytes = bytes("café", "utf-8")
print(word_as_bytes)
b'caf\xc3\xa9'

Đối tượng bytes hiển thị trực tiếp ba chữ cái đầu trong café. Tuy nhiên, ký tự có dấu é không thuộc ASCII và được biểu diễn bằng hai byte, được hiển thị là \xc3 và \xa9. Các byte này biểu diễn các số hệ thập lục phân c3 và a9, tức là các số nguyên 195 và 169. Hai byte này kết hợp lại biểu diễn é trong UTF-8:

print(len(word_as_bytes))
print(list(word_as_bytes))
5
[99, 97, 102, 195, 169]

Một đối tượng bytes gồm năm phần tử biểu diễn chuỗi bốn ký tự.

Chuyển đổi chuỗi sang bytes: Phương thức encode()

Trước đó, chúng ta dùng hàm tạo bytes() để chuyển một chuỗi văn bản thành đối tượng bytes. Cách thường gặp hơn để chuyển chuỗi Python sang bytes là dùng phương thức chuỗi .encode(), cho phép kiểm soát bảng mã và xử lý lỗi. Phương thức này trả về một đối tượng bytes đại diện cho chuỗi:

word_as_bytes = "Hello Python!".encode()
​print(word_as_bytes)
print(type(word_as_bytes))
b'Hello Python!'
<class 'bytes'>

Phương thức .encode() mặc định dùng bảng mã UTF-8. UTF-8 là định dạng mã hóa được sử dụng rộng rãi nhất và hỗ trợ dải ký tự rộng hơn nhiều so với ASCII. UTF-8 biểu diễn mỗi ký tự bằng một chuỗi gồm một, hai, ba hoặc bốn đơn vị byte.

Chúng ta có thể gọi .encode() với một bảng mã khác làm đối số:

word_as_bytes = "Hello Python!".encode("utf-16")
print(word_as_bytes)
b'\xff\xfeH\x00e\x00l\x00l\x00o\x00 \x00P\x00y\x00t\x00h\x00o\x00n\x00!\x00'

Đối tượng bytes trong trường hợp này khác đi vì nó biểu diễn mã hóa UTF-16 của cùng chuỗi văn bản.

Lỗi mã hóa

Vì không phải bảng mã nào cũng bao gồm tất cả ký tự, lỗi có thể xảy ra khi mã hóa một chuỗi thành đối tượng bytes.

Hãy xét chuỗi "Café • £2.20", trong đó có ba ký tự không thuộc ASCII. Ta có thể mã hóa chuỗi này bằng UTF-8 mặc định:

word_as_bytes = "Café • £2.20".encode()
print(word_as_bytes)
b'Caf\xc3\xa9 \xe2\x80\xa2 \xc2\xa32.20'

Các ký tự không thuộc ASCII được thay bằng các chuỗi escape thập lục phân. Tuy nhiên, .encode() sẽ phát sinh lỗi nếu cùng chuỗi đó được mã hóa bằng ASCII vì có một số ký tự không tồn tại trong bảng mã ASCII:

word_as_bytes = "Café • £2.20".encode("ascii")
print(word_as_bytes)
Traceback (most recent call last):
...
word_as_bytes = "Café • £2.20".encode("ascii")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 3: ordinal not in range(128)

Phương thức chuỗi .encode() có tham số errors với giá trị mặc định là "strict". Đối số "strict" buộc .encode() ném ra UnicodeEncodeError khi có ký tự không thể mã hóa.

Tuy vậy, có các lựa chọn khác để xử lý lỗi. Một lựa chọn là bỏ qua lỗi bằng đối số "ignore":

word_as_bytes = "Café • £2.20".encode("ascii", errors="ignore")
print(word_as_bytes)
b'Caf 2.20'

Tùy chọn này không phát sinh lỗi. Thay vào đó, .encode() trả về một đối tượng bytes, và ký tự é có dấu, dấu đầu dòng và ký hiệu bảng Anh bị lược bỏ.

Một lựa chọn khác là thay thế các ký tự không thể mã hóa bằng thứ khác. Có một vài lựa chọn thay thế. Một trong số đó là đối số errors="replace":

word_as_bytes = "Café • £2.20".encode("ascii", errors="replace")
print(word_as_bytes)
b'Caf? ? ?2.20'

Ba ký tự không thuộc ASCII, vốn không thể mã hóa trong ví dụ này, được thay bằng dấu hỏi. Vì vậy, mỗi ký tự thiếu được thay bằng một ký tự đơn khác đóng vai trò giữ chỗ.

Chúng ta cũng có thể thay thế các ký tự thiếu bằng văn bản giàu thông tin hơn:

word_as_bytes = "Café • £2.20".encode("ascii", errors="backslashreplace")
print(word_as_bytes)
b'Caf\\xe9 \\u2022 \\xa32.20'

Gọi .encode() với errors="backslashreplace" sẽ thay các ký tự không thể mã hóa bằng chuỗi escape thập lục phân tương ứng. Số thập lục phân e9 biểu diễn ký tự é có dấu. Dấu đầu dòng là ký tự Unicode u2022, và số thập lục phân a3 biểu diễn ký hiệu bảng Anh.

Chúng ta cũng có thể dùng "xmlcharrefreplace" để thay các ký tự thiếu bằng mã XML của chúng:

word_as_bytes = "Café • £2.20".encode("ascii", errors="xmlcharrefreplace")
print(word_as_bytes)
b'Caf&#233; &#8226; &#163;2.20'

Một lựa chọn khác là thay thế các ký tự không hợp lệ bằng tên chính thức của chúng, dùng errors="namereplace":

word_as_bytes = "Café • £2.20".encode("ascii", errors="namereplace")
print(word_as_bytes)
b'Caf\\N{LATIN SMALL LETTER E WITH ACUTE} \\N{BULLET} \\N{POUND SIGN}2.20'

Tùy tình huống mà cần cách xử lý lỗi phù hợp, và phương thức chuỗi .encode() cung cấp nhiều tùy chọn để xử lý các ký tự không thể mã hóa.

Ứng dụng của chuyển đổi chuỗi sang bytes trong khoa học dữ liệu

Chuyển đổi chuỗi sang bytes là một thao tác nền tảng, có ứng dụng trong nhiều lĩnh vực khoa học dữ liệu:

  • Xử lý ngôn ngữ tự nhiên (NLP): Khi làm việc với dữ liệu văn bản cho các tác vụ như phân tích cảm xúc, mô hình chủ đề hoặc dịch máy, chúng ta thường tiền xử lý văn bản bằng cách tách thành từ hoặc phân từ con. Quá trình này thường liên quan đến việc chuyển chuỗi thành dãy byte để biểu diễn và thao tác hiệu quả.
  • Làm sạch và tiền xử lý dữ liệu: Các thao tác ở cấp độ byte có thể hữu ích để làm sạch dữ liệu văn bản, như loại bỏ ký tự không hợp lệ hoặc chuẩn hóa văn bản dựa trên các mẫu byte cụ thể.
  • Kỹ thuật đặc trưng: Trong một số trường hợp, các đặc trưng ở cấp độ byte (ví dụ: n-gram của bytes) có thể được trích xuất từ dữ liệu văn bản và dùng làm đầu vào cho mô hình học máy.
  • Thu thập dữ liệu web và trích xuất dữ liệu: Khi thu thập dữ liệu từ trang web, ta thường nhận được HTML hoặc nội dung dạng văn bản khác có thể cần được phân tích và xử lý ở cấp độ byte để trích xuất thông tin liên quan.
  • Nén dữ liệu: Một số thuật toán nén hoạt động trên dãy byte, vì vậy việc chuyển chuỗi sang bytes có thể là bước cần thiết trước khi áp dụng kỹ thuật nén.

Hiểu các ứng dụng này giúp chúng ta nhận diện những tình huống mà việc chuyển đổi chuỗi sang bytes có thể hữu ích.

Kết luận

Chuỗi là các dãy ký tự có thể đọc được bởi con người. Những ký tự này được mã hóa thành các byte dữ liệu nhị phân, có thể được lưu trữ trong một đối tượng bytes. Một đối tượng bytes là một dãy số nguyên, mỗi số nguyên đại diện cho một byte.

Các ứng dụng yêu cầu chuỗi được chuyển thành đối tượng bytes, và chúng ta có thể chuyển bằng hàm tạo bytes() hoặc phương thức chuỗi .encode(). Thành thạo việc chuyển đổi giữa chuỗi và bytes cho phép thao tác dữ liệu linh hoạt hơn.

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:

Câu hỏi thường gặp về chuyển đổi String sang Bytes

Sự khác nhau giữa str và bytes là gì?

Chuỗi là một dãy ký tự bất biến, trong khi một đối tượng bytes là một dãy số nguyên bất biến. Mỗi số nguyên đại diện cho một byte.

Tôi nên dùng bytes() hay str.encode() để chuyển chuỗi thành bytes?

Phương thức str.encode() là cách ưu tiên để chuyển chuỗi sang bytes trong Python, vì nó rõ ràng và linh hoạt trong việc chọn bảng mã và chiến lược xử lý lỗi. Hàm tạo bytes() có thể được dùng trong những tình huống cụ thể khi str.encode() không áp dụng trực tiếp.

Stephen Gruppetta

Tác giả

Stephen Gruppetta

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.

Chủ đề

Liên quan