Python2的字符串有兩種:str 和 unicode,Python3的字符串也有兩種:str 和 bytes。Python2 的 str 至關於 Python3 的bytes,而unicode至關於Python3的str。python
Python2裏面的str和unicode是能夠混用的,在都是英文字母的時候str和unicode沒有區別。而Python3 嚴格區分文本(str)和二進制數據(bytes),文本老是unicode,用str類型,二進制數據則用bytes類型表示,這樣嚴格的限制也讓咱們對如何使用它們有了清晰的認識,這是很棒的。編程
經過如下代碼咱們認識如下Python2和Python3的字符串混用狀況:網絡
# Python2中: In [1]: 'a' == u'a' Out[1]: True In [2]: 'a' in u'a' Out[2]: True In [3]: '編程' == u'編程' /usr/local/bin/ipython:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal #!/usr/bin/python Out[3]: False In [4]: '編程' in u'編程' --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-4-7b677a923254> in <module>() ----> 1 '編程' in u'編程' UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128) # Python3中: In [1]: 'a' == b'a' Out[1]: False In [2]: 'a' in b'a' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-10-ca907fd8856f> in <module>() ----> 1 'a' in b'a' TypeError: a bytes-like object is required, not 'str'
以上代碼能夠看到,Python2中str和unicode的在都是ascii碼時混用沒區別,由於unicode的ascii區域的值跟str的ascii是同樣的;而對應非ascii區域(好比中文),兩者又不同了,能夠看到Python2拋出了UnicodeDecodeError的異常,相信這也是不少人處理文本時遇到過的錯誤;‘編程’在str類型時長度是6,而在unicode時是2。不一樣字符的不一樣表現,讓Python2的str和unicode顯得撲朔迷離。python爬蟲
在Python3中,嚴格區分了str和bytes,不一樣類型之間操做就會拋出TypeError的異常。ui
上面用示例闡述了Python2和Python3中字符串的不一樣,下面主要講Python3中的字符串。編碼
一圖勝千言:spa
str和bytes的相互轉換code
str.encode(‘encoding’) -> byteshtm
bytes.decode(‘encoding’) -> str
encoding 指的是具體的編碼規則的名稱,對於中文來講,它能夠是這些值: ‘utf-8’, ‘gb2312’, ‘gbk’, ‘big5’ 等等。
不知道你有沒有注意到上圖中str矩形要比bytes矩形短,表示一樣的內容,str的長度要小於或等於bytes的長度,你能夠考慮一下緣由(參考Unicode、UTF-8的編碼規則)
下面看看具體代碼理解一下str和bytes的相互轉換:
In [16]: a = 'T恤' In [17]: a Out[17]: 'T恤' In [18]: len(a) Out[18]: 2 In [19]: b = a.encode('utf8') In [20]: b Out[20]: b'T\xe6\x81\xa4' In [21]: a == b Out[21]: False In [22]: c = a.encode('gbk') In [23]: c Out[23]: b'T\xd0\xf4' In [24]: b == c Out[24]: False In [25]: a == c Out[25]: False
上面str和bytes之間的轉換是針對文本內容的,要是其它二進制內容(好比,圖片)時,bytes就不能decode成str了,看如下代碼的異常:
In [29]: img = open('str-bytes.jpg', 'rb').read() In [30]: type(img) Out[30]: bytes In [31]: img.decode('utf8') --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-31-c9e28f45be95> in <module>() ----> 1 img.decode('utf8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
由於圖片中的二進制數據不符合文本數據的UTF-8編碼規則。
上面得到圖片數據時,咱們用到了open()來讀取文件,文件存儲的無非是文本和二進制這兩種格式,讀寫文件時也有分清楚編碼:
In [32]: open('z.txt', 'w').write('T恤') Out[32]: 2 In [33]: open('z.txt', 'w').write(img) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-33-4a88980b3a54> in <module>() ----> 1 open('z.txt', 'w').write(img) TypeError: write() argument must be str, not bytes In [34]: open('z.txt', 'wb').write(img) Out[34]: 12147
讀寫二進制數據(如圖片)時,要加’rb’參數,b代碼binary(二進制)
讀寫文本數據時,通常加’b’,open()會自動轉換bytes到str。
Python3裏面的str是在內存中對文本數據進行使用的,bytes是對二進制數據使用的。
str能夠encode爲bytes,可是bytes不必定能夠decode爲str。實際上bytes.decode(‘latin1’)能夠稱爲str,也就是說decode使用的編碼決定了decode()的成敗,一樣的,UTF-8編碼的bytes字符串用GBK去decode()也會出錯。
bytes通常來自網絡讀取的數據、從二進制文件(圖片等)讀取的數據、以二進制模式讀取的文本文件(.txt, .html, .py, .cpp等)