Làm cách nào để đọc mảng byte trong Python?

Hàm bytearray() của Python chuyển đổi các chuỗi hoặc tập hợp các số nguyên thành một chuỗi byte có thể thay đổi. Nó cung cấp cho các nhà phát triển các phương thức thông thường mà Python cung cấp cho cả kiểu dữ liệu có thể thay đổi và byte. Tích hợp bytearray() của Python cho phép thao tác dữ liệu hiệu quả cao trong một số tình huống phổ biến

Mục lục

Các tính năng mạnh mẽ của hàm Python bytearray() đi kèm với một số trách nhiệm. Các nhà phát triển phải chú ý đến mã hóa, nhận thức được định dạng dữ liệu nguồn và có kiến ​​thức làm việc cơ bản về các bộ ký tự phổ biến như ASCII

Trong bài viết này, bạn sẽ tìm hiểu lý do căn bản, các trường hợp sử dụng phổ biến, các trường hợp sử dụng nâng cao và những cạm bẫy tiềm ẩn của hàm tích hợp sẵn bytearray() của Python. Thậm chí còn có một phần với một số điều kỳ quặc đáng chú ý ở phía dưới

TL; DR — Hàm bytearray() của Python chuyển đổi chuỗi và chuỗi số nguyên thành byte để cung cấp cho nhà phát triển khả năng cập nhật (biến đổi) dữ liệu một cách hiệu quả mà không cần cấp phát bộ nhớ bổ sung

# Define a string
x = "Stay gold Ponyboy."

# Try to mutate it
x[5:9] = 'silver'

# Throws the following error
>>> TypeError: 'str' object does not support item assignment

# Define a byte array
y = bytearray(x, encoding='ascii')

# Try to mutate it
y[5:] = bytearray('silver Ponyboy.', encoding='ascii')

# Print the resulting type, decoded
# to an ascii-string
print(y.decode(encoding='ascii'))

# Results in mutated string
>>> Stay silver Ponyboy.

cơ sở lý luận

Đối tượng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 đã được giới thiệu trong Python 2 và đã đóng vai trò là ‘‘ cho đối tượng byte kể từ đó. Không giống như đối tượng
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
3, đối tượng
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 không đi kèm với biểu diễn ký hiệu theo nghĩa đen và phải được khởi tạo trực tiếp

Ví dụ:

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
5 cung cấp biểu diễn bằng chữ cho đối tượng byte trong khi nhà phát triển phải sử dụng cú pháp
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
6 để tạo đối tượng
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 mới. Tôi coi đây chỉ là một sự bất tiện nhỏ do những lợi ích mà kiểu dữ liệu
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 của Python mang lại cho các nhà phát triển

Dữ liệu như chuỗi được coi là bất biến (thêm về điều đó bên dưới) có nghĩa là chúng không thể thay đổi trực tiếp. Để thay đổi (biến đổi) một chuỗi, người phát triển phải sao chép chuỗi đó và gán phiên bản mới cho một đối tượng nằm trong bộ nhớ. Xem xét ví dụ sau

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504

Lưu ý rằng chuỗi của chúng tôi đã được thay đổi nhưng bây giờ có một id khác (vị trí bộ nhớ. ) Điều đó có nghĩa là bây giờ a là một đối tượng khác trong bộ nhớ và đối tượng ban đầu của chúng ta là rác. Đó là tất cả tốt và tốt khi một người đang thay đổi xung quanh một vài chuỗi

Thao tác chuỗi dễ dàng như vậy là một trong những tính năng ngôn ngữ khiến Python trở thành ngôn ngữ lập trình phổ biến như vậy. Thật không may, phương pháp này không hiệu quả để thay đổi số lượng lớn dữ liệu đó. Đó là nơi sức mạnh của hàm

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
9 tỏa sáng

Mô tả mục đích sử dụng của byearry() như sau

Lớp bytearray là một chuỗi các số nguyên có thể thay đổi trong phạm vi 0 <= x < 256. Nó có hầu hết các phương thức thông thường của các chuỗi có thể thay đổi, được mô tả trong Các loại chuỗi có thể thay đổi, cũng như hầu hết các phương thức mà loại byte có, xem Hoạt động của byte và Bytearray

Tham chiếu đến tài liệu cũng không nên được chuyển qua. Tài liệu tham khảo đó cung cấp các chi tiết sau đây

Vì 2 chữ số thập lục phân tương ứng chính xác với một byte đơn, số thập lục phân là định dạng thường được sử dụng để mô tả dữ liệu nhị phân.  

Điều này sẽ có ý nghĩa hơn chỉ sau một chút khi chúng ta xem xét các trường hợp hàm bytearray() hiển thị các chuỗi ký tự thoát. Bây giờ, hãy xem xét một số trường hợp phổ biến và cú pháp cơ bản

Sử dụng cơ bản và cú pháp

Hàm bytearray() trả về một mảng byte mới. Điều này có thể xuất phát từ một chuỗi đầu vào hoặc một tập hợp các số nguyên trong phạm vi 0-255 (bao gồm). Nếu bạn đã quen thuộc với ký hiệu nhị phân, bạn có thể đã đoán được rằng nó tạo ra chỗ ở hoàn hảo cho các biểu diễn tám bit

bytearray() tích hợp sẵn của Python có ba đối số có thể

  1. nguồn – dữ liệu được chuyển đổi thành một mảng byte, một chuỗi hoặc một tập hợp các số nguyên
  2. mã hóa - bắt buộc đối với chuỗi, tùy chọn đối với bộ sưu tập số nguyên
  3. lỗi - một tham số tùy chọn để chỉ định xử lý lỗi.

Hãy xem nhanh hàm bytearray() để chứng minh cách sử dụng cơ bản của các đối số này

# create a bytearray from a string
>>> bytearray("byte-sized")

TypeError: string argument without an encoding

Chà, điều đó đã không diễn ra tốt đẹp. Byte cần thiết chỉ là biểu diễn số của thông tin. Không biết cách diễn giải thông tin đó, Python sẽ làm ầm lên. Có thể cho rằng, một mã hóa mặc định có thể được sử dụng nhưng điều đó sẽ gây ra một loạt vấn đề khác. Hãy xem điều gì sẽ xảy ra khi chúng ta để Python biết cách diễn giải dữ liệu

# create a bytearray from a string, specify encoding
>>> bytearray("Byte-sized", encoding='ascii')

bytearray(b'Byte-sized')

Bây giờ chúng ta có một đối tượng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 trong bộ nhớ biểu thị nhiều bằng cách hiển thị một byte bằng chữ trong dấu ngoặc đơn (thêm về điều đó bên dưới. ) Chúng ta hãy xem cách hàm bytearray() xử lý một chuỗi các giá trị số nguyên. Hãy nhớ rằng, chỉ những giá trị trong phạm vi
# create a bytearray from a string
>>> bytearray("byte-sized")

TypeError: string argument without an encoding
6 mới được coi là hợp lệ tại đây

# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument

Chà, điều đó cũng không suôn sẻ. Khi được cung cấp một dãy số, Python không cần biết mã hóa vì nó giới hạn các giá trị từ 0-255. Biểu diễn ký tự của bất kỳ giá trị nào trong phạm vi này được giả định là theo tiêu chuẩn ISO8859-1, thường được gọi là bộ ký tự Latinh-1 (bộ ký tự thay thế của bảng mã ASCII. ) Hãy thử điều này một lần nữa

# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')

Bây giờ chúng ta có một đối tượng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 từ danh sách các giá trị số nguyên. Nhưng chúng ta có thể làm gì với điều này? . Chúng tôi sẽ đề cập đến những gì có thể thay đổi so với. phương tiện bất biến chỉ trong một giây. Tuy nhiên, trước khi đến đó, chúng ta hãy dừng lại một chút và xem xét sự khác biệt giữa chuỗi byte và mảng byte có thể là gì

Chuỗi byte so với. Mảng byte

Tại thời điểm này, bạn có thể tự hỏi sự khác biệt giữa chuỗi byte và tập hợp byte có thể là gì. Trong một từ-độ biến đổi. Cả hai đều biểu thị dữ liệu ở định dạng nhị phân, cả hai đều có thể dễ dàng xử lý các đầu vào thập lục phân hai chữ số và cả hai đều dựa vào các nhà phát triển để lưu tâm đến mã hóa để đảm bảo biểu thị chính xác các giá trị số và bản dịch kết quả. Vì vậy, những gì cho?

Các byte được xử lý hữu hạn hơn các đối tượng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2. Nghĩa là, chúng phù hợp với các ứng dụng mà người ta không cần thay đổi dữ liệu thường xuyên. Ví dụ: một đối tượng byte sẽ phù hợp hơn để lưu trữ dữ liệu nhận được từ đường truyền mạng. Đối với các lần truyền lớn, thậm chí có thể dưới dạng một mảng byte (chứ không phải đối tượng
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2. )

Đối tượng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 phù hợp hơn với các tình huống cần thao tác dữ liệu thường xuyên. Ví dụ: cập nhật dữ liệu nhận được từ truyền mạng trước khi truyền lại. Các đối tượng
# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
2 cũng cung cấp các phương thức dành cho các đối tượng có thể thay đổi như định cỡ, cắt, gán thành viên, chèn, đảo ngược, v.v.

Để đánh giá đầy đủ sự khác biệt giữa các byte Python và các đối tượng

# create a bytearray from a string, specify encoding
>>> bytearray("Byte-sized", encoding='ascii')

bytearray(b'Byte-sized')
3, chúng ta sẽ cần xem xét sự khác biệt giữa có thể thay đổi và. kiểu dữ liệu bất biến. Đừng lo lắng, đó là một khái niệm khá đơn giản và với một ví dụ cơ bản rất dễ nắm bắt

Có thể thay đổi so với. bất biến

Trong Python, chuỗi, số và bộ dữ liệu là bất biến—có nghĩa là không thể thay đổi giá trị của chúng. Chúng có thể được sao chép hoặc gán lại nhưng không được thao tác trực tiếp. Các cấu trúc dữ liệu như danh sách, từ điển và tập hợp có thể thay đổi được và cho phép thao tác các phần cấu thành của chúng hiệu quả hơn nhiều

Cụ thể, việc cấp phát bộ nhớ bổ sung được giảm thiểu khi cập nhật một phần dữ liệu nằm ở giữa danh sách trong khi việc cập nhật ở giữa chuỗi sẽ yêu cầu bộ nhớ gần gấp đôi. Điều này mô tả cách các mảng byte có thể được áp dụng trong việc biểu diễn các kiểu dữ liệu không thay đổi để cải thiện hiệu quả trong các ngữ cảnh nhất định

Hãy xem lại ví dụ TL; DR ban đầu của chúng tôi từ phía trên, lần này có thêm một chút giải thích

# Define a string
x = "stay gold Ponyboy."

# Try to mutate it
x[5:9] = 'silver'

>>> TypeError: 'str' object does not support item assignment

# Define a byte array
y = bytearray(x, encoding='ascii')

# Try to mutate it
y[5:] = bytearray('silver Ponyboy.', encoding='ascii')

>>> bytearray(b'stay silver Ponyboy.')

# assign new value to z, check type
z = y.decode(encoding='ascii')

z, type(z)

>>> (stay silver Ponyboy., 

Ở đây, chúng tôi đã chỉ ra rằng việc cố gắng thay đổi trực tiếp văn bản của chuỗi của chúng tôi sẽ tạo ra một

# create a bytearray from a string, specify encoding
>>> bytearray("Byte-sized", encoding='ascii')

bytearray(b'Byte-sized')
4. Lưu trữ chuỗi đó dưới dạng một mảng byte cho phép thao tác trực tiếp các giá trị ký tự riêng lẻ. Sau khi thao tác, chúng ta có thể chuyển đổi các giá trị kết quả thành một chuỗi thông qua phương thức
# create a bytearray from a string, specify encoding
>>> bytearray("Byte-sized", encoding='ascii')

bytearray(b'Byte-sized')
5—đảm bảo chỉ định mã hóa phù hợp

Đây có phải là một ví dụ về việc sử dụng hiệu quả hàm bytearray() không? . Hãy tưởng tượng bạn phải cập nhật các chuỗi dữ liệu văn bản lớn, chẳng hạn như trong nhiều ứng dụng cơ sở dữ liệu hoặc mức tiêu thụ dữ liệu mạng lớn. Khả năng thao tác dữ liệu mà không cần cấp phát bộ nhớ bổ sung sẽ rất cần thiết. Đó là nơi các mảng byte thực sự tỏa sáng

TL; DR – biểu diễn một chuỗi dưới dạng một mảng byte cho phép một người thao tác với nó hiệu quả hơn. Có một chi phí chung ban đầu trong bộ nhớ nhưng chi phí giảm dần khi các hoạt động thao tác tích lũy. Luôn nhớ mã hóa của bạn

ghi chú

Hàm bytearray() xử lý một số tiện ích khá sắc thái. Điều này không gây ngạc nhiên về hành vi đôi khi ma quái được thể hiện bởi tính năng tích hợp sẵn này. Dưới đây là một số trường hợp mà hàm bytearray() có thể hoạt động theo những cách cần được giải thích. Đây chắc chắn không phải là lỗi nhưng dù sao cũng nên ghi nhớ

Chuỗi ký tự thoát

Với giới hạn bytearray() của các đối số số nguyên hợp lệ trong phạm vi

# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
0, người ta có thể mong đợi một số hành vi nhanh chóng phát sinh. Một
# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
1 bị loại bỏ bất cứ khi nào một giá trị không tuân thủ được thử—nhưng điều đó được mong đợi. Điều kỳ lạ là cách Python sẽ biểu thị các giá trị thứ tự cho các ký tự không in được. Hãy xem xét những điều sau đây

# create an array of nums
>>> nums = [1, 2, 3, 4, 5]

# Create bytearry by reference
>>> bytearray(nums)

bytearray(b'\x01\x02\x03\x04\x05')

# Declare a bytearray of list literal
>>> bytearray([1, 2, 3, 4, 5])

bytearray(b'\x01\x02\x03\x04\x05')

# Declare a bytearray with some known printable ASCII values
print(bytearray([65, 1, 97, 2, 66, 3, 98]))

bytearray(b'A\x01a\x02B\x03b')

Lưu ý rằng

# Create a string
a = "string one"
print(a, "-", id(a))

>>> string one - 3236722728688

# 'mutate' string
a = "string two"
print(a, "-", id(a))

>>> string two - 3236720675504
9 sẽ hiển thị các ký tự thoát bất kể mảng số nguyên được truyền vào như thế nào (tiền tố
# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
3. ) Tuy nhiên, lưu ý rằng các ký tự có giá trị số nguyên khớp với giá trị thứ tự của các ký tự có thể in được biểu thị dưới dạng ký tự đó. Nói cách khác. 1 được hiển thị dưới dạng
# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
4 nhưng
# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
5 được hiển thị dưới dạng
# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
6 vì đó là giá trị thứ tự của một ký tự có thể in được. Hãy xem bài viết về hàm ord() của Python để cảm nhận về khả năng tương tác đó

Giá trị mặc định

bytearray() có thể được khởi tạo dưới dạng một mảng trống hoặc một mảng có giá trị mặc định bằng cách chuyển một đối số số nguyên không thể lặp lại. Hãy xem xét những điều sau đây

# Create an empty bytearray
>>> bytearray()

bytearray(b'')

# Create a byte array of size 5
>>> bytearray(5)

bytearray(b'\x00\x00\x00\x00\x00')

# Create a byte array with single
# element 5
>>> bytearray([5])

bytearray(b'\x05')

Lưu ý ở đây rằng việc chuyển giá trị số nguyên của

# creat a bytearry of integers from ordinal values of a string
>>> bytearray([ord(x) for x in "Byte-sized"], encoding='ascii')

TypeError: encoding without a string argument
8 làm đối số sẽ khởi tạo đối tượng bytearray() với năm giá trị là
# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')
0—được biểu thị bằng chuỗi ký tự thoát
# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')
1. Theo tôi, tài liệu bao gồm các đối số bytearray() hợp lệ không hoàn toàn rõ ràng về điểm này và có thể dẫn đến một số nhầm lẫn. Lưu ý ví dụ cuối cùng đặt 5 trong ký hiệu danh sách ngoặc của Python. Điều này dẫn đến một đối tượng bytearray() có độ dài một với chuỗi ký tự thoát duy nhất là
# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')
4. Một lần nữa, không phải là một lỗi nhưng chắc chắn kỳ quặc. Ghi chú.
# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')
0 không giống như
# creat an array of ints from a string
nums = [ord(x) for x in "Byte-sized"]

[66, 121, 116, 101, 45, 115, 105, 122, 101, 100]

# Instantiate a byte array
>>> bytearray(nums)

bytearray(b'Byte-sized')
6

Suy nghĩ cuối cùng

Hàm bytearray() của Python cung cấp một tiện ích dễ sử dụng để thao tác dữ liệu hiệu quả với bộ nhớ. Các nhà phát triển ứng dụng mạng, các trường hợp sử dụng xử lý chuỗi lớn và các chương trình mã hóa và giải mã các dải dữ liệu lớn đều có thể ngưỡng mộ khả năng truy cập cấp cao của dữ liệu đòn bẩy thấp

Python chắc chắn không phải là ngôn ngữ chuẩn để phát triển các ứng dụng hiệu quả về bộ nhớ—ít nhất là không trực tiếp. Hàm bytearray() cung cấp tiện ích tạo ra trường hợp, mặc dù không phải là lựa chọn chính tắc, nhưng Python chắc chắn sẽ hoàn thành nhiệm vụ nếu cần. Để biết thêm thông tin chi tiết về việc xử lý dữ liệu nhị phân, hãy xem bài viết Dù sao thì luồng byte là gì?

Làm cách nào để đọc dữ liệu byte trong Python?

bạn có thể sử dụng bin(ord('b')) . replace('b', '') bin() nó cung cấp cho bạn biểu diễn nhị phân với 'b' sau bit cuối cùng, bạn phải xóa nó. Ngoài ra, ord() cung cấp cho bạn số ASCII cho ký tự được mã hóa char hoặc 8-bit/1 Byte.

Kiểu dữ liệu mảng byte trong Python là gì?

Loại bytearray là một chuỗi số nguyên có thể thay đổi trong phạm vi 0 . Nó có hầu hết các phương thức thông thường của các chuỗi có thể thay đổi, được mô tả trong Các loại chuỗi có thể thay đổi, cũng như hầu hết các phương thức mà loại byte có, xem Phương thức mảng byte và byte.

Làm cách nào để chuyển đổi mảng byte thành chuỗi trong Python?

Các cách khác nhau để chuyển đổi Byte thành chuỗi trong Python. .
Sử dụng phương thức giải mã()
Sử dụng hàm str()
Sử dụng codec. phương pháp giải mã ()
Sử dụng map() mà không sử dụng tiền tố b
Sử dụng gấu trúc để chuyển đổi byte thành chuỗi

Làm cách nào để chuyển đổi mảng byte thành số nguyên trong Python?

cú pháp. int. from_bytes(byte, thứ tự byte, *, đã ký=Sai)
Thông số
Trả về - một int tương đương với byte đã cho