程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python | bytes 與 str 的區別

編輯:Python

本文主要介紹在 Pythonbytesstr 的區別。1
Updated: 2022 / 6 / 16


bytes 與 str 的區別

  • 參考鏈接

1. Python 有兩種類型可以表示字符序列

  • bytes
    下面所示實例包含的是原始數據 ,即 8 位的無符號值(通常按照 ASCII編碼 標准來顯示)
  • str
    下面所示實例包含的是 Unicode 碼點(code point,也叫作代碼點),這些碼點與人類語言之中的文本字符相對應
a = b'h\x6511o'
print(list(a))
# [104, 101, 49, 49, 111]
print(a)
# b'he11o' 
a = 'a\\u300 propos'
print(list(a))
# ['a', '\\', 'u', '3', '0', '0', ' ', 'p', 'r', 'o', 'p', 'o', 's']
print(a)
# a\u300 propos

2.Unicode 數據和二進制數據轉換

  • Unicode 數據轉換成二進制數據,必須調用 strencode 方法(編碼)
FileContent = 'This is file content.'
print(FileContent)
# 'This is file content.'
print(type(FileContent))
# <class 'str'>
FileContent = FileContent.encode(encoding='utf-8')
print(FileContent)
# b'This is file content.'
print(type(FileContent))
# <class 'bytes'>
  • 把二進制數據轉換成 Unicode 數據,必須調用 bytesdecode 方法(解碼)
FileContent = b'This is file content.'
print(FileContent)
# b'This is file content.'
print(type(FileContent))
# <class 'bytes'>
FileContent = FileContent.decode(encoding='utf-8')
print(FileContent)
# 'This is file content.'
print(type(FileContent))
# <class 'str'>

調用這些方法時,可以明確指出字符集編碼,也可以采用系統默認的方案,通常是 UTF-8

當前操作系統默認的字符集編碼,Python 一行代碼查看當前操作系統默認的編碼標准: 在 cmd 中執行:

python3 -c 'import locale; print(locale.getpreferredencoding())'
# UTF-8

3. 使用原始的 8 位值與 Unicode 字符串
使用原始的 8 位值與 Unicode 字符串時需要注意的兩個問題 (該問題等價於使用 bytesstr 時需要注意的兩個問題):

  • 3.1bytesstr 的互不兼容

使用 + 操作符

# bytes+bytes
print(b'a' + b'1')
# b'a1'
# str+str
print('b' + '2')
# b2
# bytes+str
print('c' + b'2')
# TypeError: can only concatenate str (not "bytes") to str

同類型之間也可以用二元操作符來比較大小

# bytes bytes
assert b'c' > b'a'
assert b'c' < b'a'
# AssertionError
print(b'a' == b'a')
# True
# str str
assert 'c' > 'a'
assert 'c' < 'a'
# AssertionError
print('a' == 'a')
# True
# bytes str
assert b'c' > 'a'
# TypeError: '>' not supported between instances of 'bytes' and 'str'
print('a' == b'a')
# False

格式化字符串中的 %s

兩種類型的實例都可以出現在 % 操作符的右側,用來替換左側那個格式字符串(format string)裡面的 %s。但是如果格式字符串是 bytes 類型,那麼不能用 str 實例來替換其中的 %s,因為 Python 不知道這個 str 應該按照什麼字符集來編碼。

# bytes % str
print(b'red %s' % 'blue'
# TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str'
# str % bytes 
print('red %s' % b'blue')
# red b'blue'
# @ 這樣會讓系統在 bytes 實例上面調用 __repr__ 方法。調用結果替換格式字符串裡的 %s,因此程序會直接輸出 b'blue',而不是輸出 blue
  • 3.2 操作文件句柄時需要使用 Unicode 字符串操作, 不能使用原始的 bytes

w 模式必須以 ‘文本’ 模式寫入, 否則向文件寫入二進制數據會報錯:

# 寫入二進制數據
with open('test.txt', "w+") as f:
f.write(b"\xf1\xf2")
# TypeError: write() argument must be str, not bytes

wb 可正常寫入二進制數據

# 寫入二進制數據
with open('test.txt', "wb") as f:
f.write(b"\xf1\xf2")

r 模式必須以 ‘文本’ 模式寫入, 否則從文件讀取二進制數據會報錯:

# 讀取二進制數據
with open('test.txt', "r+") as f:
f.read()
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte
# @以文本模式操縱文件句柄時,系統會采用 默認的文本編碼 方案處理二進制數據。所以,上面那種寫法會讓系統通過 `bytes.decode` 把這份數據解碼成 `str` 字符串,再用 `str.encode` 把字符串編碼成二進制值。然而對於大多數系統來說,默認的文本編碼方案是 `UTF-8`,所以系統很可能會把 `b'\xf1\xf2\xf3\xf4\xf5'` 當成 `UTF-8` 格式的字符串去解碼,於是就會出現上面那樣的錯誤。

rb 可正常讀取二進制數據

# 寫入二進制數據
with open('test.txt', "rb") as f:
print(b"\xf1\xf2" == f.read())
# True

另一種改法,設置 encoding 參數指定字符串編碼:

with open('test.txt', "r", encoding="cp1252") as f:
print(f.read())


補充說明:




參考鏈接


  1. Python bytes 與 str 的區別︎


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved