在Python 3版本中,把'xxx'和u'xxx'統一成Unicode編碼,即寫不寫前綴u都是同樣的。python
在Python 3版本中,全部的字符串都是使用Unicode編碼的字符串序列。ide
Python 3最重要的新特性之一是對字符串和二進制數據流作了明確的區分。文本老是 Unicode,由 str 類型表示,二進制數據則由 bytes 類型表示。Python 3 不會以任意隱式的方式混用 str 和 bytes ,你不能拼接字符串和字節流,也沒法在字節流裏搜索字符串(反之亦然),也不能將字符串傳入參數爲字節流的函數(反之亦然)。函數
# -*- coding: utf-8 -*- import sys # 查看默認編碼 print(sys.getdefaultencoding()) # utf-8 b = b'\xe4\xb8\xad\xe5\x9b\xbd' # py3定義bytes使用 b = b'dfja' print(b, type(b)) # b'\xe4\xb8\xad\xe5\x9b\xbd' <class 'bytes'> b_decode = b.decode('utf-8') print(b_decode, type(b_decode)) # 中國 <class 'str'> s = '中國' # Python3中定義的字符串(str)默認就是 unicode字符串 print(s, type(s)) # 中國 <class 'str'> # s1 = s.decode("utf-8") # AttributeError: 'str' object has no attribute 'decode' ← Python3中字符串再也不有decode方法 s2 = s.encode("gbk") # 將字符串(str)用 「gbk字符編碼」 編碼爲 「gbk字符編碼的字節」 print(s2, type(s2)) # b'\xd6\xd0\xb9\xfa' <class 'bytes'> s22 = s2.decode('gbk') # 將 「字節串」 用 「gbk字符編碼」 解碼 爲 「字符串(str)」 print(s22, type(s22)) # 中國 <class 'str'> s3 = s.encode("utf-8") print(s3, type(s3)) # b'\xe4\xb8\xad\xe5\x9b\xbd' <class 'bytes'> s33 = s.encode("utf-8").decode('utf-8') print(s33, type(s33)) # 中國 <class 'str'>
bytes和str之間的異同
回到bytes和str的身上。bytes是一種比特流,它的存在形式是01010001110這種。咱們不管是在寫代碼,仍是閱讀文章的過程當中,確定不會有人直接閱讀這種比特流,它必須有一個編碼方式,使得它變成有意義的比特流,而不是一堆晦澀難懂的01組合。由於編碼方式的不一樣,對這個比特流的解讀也會不一樣,對實際使用形成了很大的困擾。下面讓咱們看看Python是如何處理這一系列編碼問題的:編碼
>>> s = "中文" >>> s '中文' >>> type(s) <class 'str'> >>> b = bytes(s, encoding='utf-8') >>> b b'\xe4\xb8\xad\xe6\x96\x87' >>> type(b) <class 'bytes'>
從例子能夠看出,s是個字符串類型。Python有個內置函數bytes()能夠將字符串str類型轉換成bytes類型,b其實是一串01的組合,但爲了在ide環境中讓咱們相對直觀的觀察,它被表現成了b'\xe4\xb8\xad\xe6\x96\x87'這種形式,開頭的b表示這是一個bytes類型。\xe4是十六進制的表示方式,它佔用1個字節的長度,所以」中文「被編碼成utf-8後,咱們能夠數得出一共用了6個字節,每一個漢字佔用3個,這印證了上面的論述。在使用內置函數bytes()的時候,必須明確encoding的參數,不可省略。code
咱們都知道,字符串類str裏有一個encode()方法,它是從字符串向比特流的編碼過程。而bytes類型剛好有個decode()方法,它是從比特流向字符串解碼的過程。除此以外,咱們查看Python源碼會發現bytes和str擁有幾乎如出一轍的方法列表,最大的區別就是encode和decode。utf-8
從實質上來講,字符串在磁盤上的保存形式也是01的組合,也須要編碼解碼。unicode
若是,上面的闡述還不能讓你搞清楚二者的區別,那麼記住下面兩幾句話:字符串
在將字符串存入磁盤和從磁盤讀取字符串的過程當中,Python自動地幫你完成了編碼和解碼的工做,你不須要關心它的過程。get
使用bytes類型,實質上是告訴Python,不須要它幫你自動地完成編碼和解碼的工做,而是用戶本身手動進行,並指定編碼格式。源碼
Python已經嚴格區分了bytes和str兩種數據類型,你不能在須要bytes類型參數的時候使用str參數,反之亦然。這點在讀寫磁盤文件時容易碰到。
在bytes和str的互相轉換過程當中,實際就是編碼解碼的過程,必須顯式地指定編碼格式。.
>>> b b'\xe4\xb8\xad\xe6\x96\x87' >>> type(b) <class 'bytes'> >>> s1 = str(b) >>> s1 "b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'" >>> type(s1) <class 'str'> >>> s1 = str(b, encoding='utf-8') >>> s1 '中文' >>> type(s1) <class 'str'>
咱們再把字符串s1,轉換成gbk編碼的bytes類型:
>>> s1 '中文' >>> type(s1) <class 'str'> >>> b = bytes(s1, encoding='gbk') >>> b b'\xd6\xd0\xce\xc4'