Python字元與位元組新編

自動化程式碼美學發表於2021-06-11

字元

字元是一個資訊單位,簡單來講就是一個字母、數字、標點符號、漢字等。

字元的最佳定義是Unicode字元:

image-20210607090732870

它是一個全球化的標準,能表示世界上所有語言的字元。Unicode字元的標識(碼位)是以4~6個十六進位制數字表示的,並且加字首U+

位元組

位元組是計算機資訊計量單位,一個位元組代表八個位元,儲存的數值範圍為0~255。

位元組跳動(ByteDance)網際網路公司的位元組就是這個位元組。

位元組是機器的,字元是人類的。

把人類字元轉換為機器位元組時使用的演算法叫做編碼,反之叫做解碼。

演算法不同,位元組與字元的關係也不同:

image-20210607093222333

bytes和bytearray

位元組實際上是個二進位制序列。不可變bytes型別和可變bytearray型別是用來儲存二進位制序列的,它們的示例如下:

>>> cafe = bytes("café", encoding="utf_8")
>>> cafe
b'caf\xc3\xa9'
>>> cafe[0]
99
>>> cafe[:1]
b'c'
>>> cafe_arr = bytearray(cafe)
>>> cafe_arr
bytearray(b'caf\xc3\xa9')
>>> cafe_arr[-1:]
bytearray(b'\xa9')

特別的是cafe[0]返回了整數,cafe[:1]返回了二進位制序列,這是因為s[0] == s[:1]只對str型別成立,而對於其他型別來說,s[i]返回一個元素,s[i:i+1]返回一個相同型別的序列。

二進位制序列實際上是整數序列。它們的字面量表示法包含ASCII字元(ASCII只能表示英文體系的字元),比如cafe的b'caf\xc3\xa9',具體規則是:

  • 從空格到~的字元直接使用ASCII字元
  • 製表符\t、換行符\n、回車符\r、轉義符\\
  • 其他字元用十六進位制轉義序列,比如\x00空位元組

構建bytes和bytearray物件的方式有以下幾種:

  1. 一個str物件和一個encoding關鍵字引數
  2. 一個可迭代物件,數值在0~255
  3. 一個實現了緩衝協議的物件,如bytes、bytearray、memoryview、array.array

memoryview和struct

memoryview允許在二進位制資料結構之間共享記憶體,struct能從序列中提取結構化資訊。

示例如下,提取一個GIF影像的寬度和高度:

import struct

with open("filter.gif", "rb") as fp:
    img = memoryview(fp.read())

# 這裡不會複製位元組序列,因為用的memoryview
header = img[:10]
print(bytes(header))  # b'GIF89a+\x02\xe6\x00'

# <是小位元組序,3s3s是兩個3位元組序列,HH是兩個16位二進位制整數
# 型別、版本、寬度、高度
struct.unpack("<3s3sHH", header)  # (b'GIF', b'89a', 555, 230)

# 刪除引用,釋放memoryview例項所佔的記憶體
del header
del img

小結

本文介紹了字元和位元組的概念以及它們之間的關係,一個字元對應一個或多個位元組。字元是人類的,位元組是機器的,編碼就是人類字元轉換為機器位元組,反之叫做解碼。然後分別介紹了二進位制序列的型別bytes和bytearray,和二進位制序列的工具memoryview和struct。

參考資料:

《流暢的Python》

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

https://zh.wikipedia.org/wiki/字元_(電腦科學)

https://home.unicode.org/

https://zh.wikipedia.org/wiki/位元組

https://www.runoob.com/w3cnote/byte-character.html

相關文章