預備知識:
bin():
""" Return the binary representation of an integer. >>> bin(2796202) '0b1010101010101010101010' """ pass
ord():
""" Return the Unicode code point for a one-character string. """
bytes類
""" bytes(iterable_of_ints) -> bytes bytes(string, encoding[, errors]) -> bytes bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer bytes(int) -> bytes object of size given by the parameter initialized with null bytes bytes() -> empty bytes object Construct an immutable array of bytes from: - an iterable yielding integers in range(256) - a text string encoded using the specified encoding - any object implementing the buffer API. - an integer """
python3中,字符串是unicode格式,字節包括utf-8,gbk等等,網絡傳輸,硬盤保存是以字節格式保存的。
str和bytes格式的區別:
str:
表現形式:a='hello,world'
內部原理:00000000 00000000 00000000 01101000 ‘h’
。。。
。。。
bytes:
表現形式:a=b'hello,world'
內部原理:
01101000 utf-8
。。。
。。。
00000000 01101000 gbk
。。。
。。。
Bytes 對象是由單個字節作為基本元素(8位,取值范圍 0-255)組成的序列,為不可變對象。
Bytes 對象只負責以二進制字節序列的形式記錄所需記錄的對象,至於該對象到底表示什么(比如到底是什么字符)則由相應的編碼格式解碼所決定。我們可以通過調用 bytes() 類(沒錯,它是類,不是函數)生成 bytes 實例,其值形式為 b'xxxxx',其中 'xxxxx' 為一至多個轉義的十六進制字符串(單個 x 的形式為:\xHH,其中 \x 為小寫的十六進制轉義字符,HH 為二位十六進制數)組成的序列,每兩個十六進制數即每個‘x’代表一個字節(八位二進制數,取值范圍 0-255),對於同一個字符串如果采用不同的編碼方式生成 bytes 對象,就會形成不同的值。
Python 3最重要的新特性大概要算是對文本和二進制數據作了更為清晰的區分。文本總是Unicode,由str類型表示,二進制數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes,正是這使得兩者的區分特別清晰。你不能拼接字符串和字節包,也無法在字節包里搜索字符串(反之亦然),也不能將字符串傳入參數為字節包的函數(反之亦然 )。
例如:
a='你好' a_b=a.encode('utf-8') print(a_b) for i in a_b: print(i) for i in a_b: print(bin(i))
輸出:
b'\xe4\xbd\xa0\xe5\xa5\xbd' #原來如此,\xe4 長得這么丑,實際是十六進制的數字。和128,12,沒什么本質的區別。自然就可以bin()變為二進制數字了。 228 189 160 229 165 189 0b11100100 0b10111101 0b10100000 0b11100101 0b10100101 0b10111101
回到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
的參數,不可省略。
我們都知道,字符串類str
里有一個encode()
方法,它是從字符串向比特流的編碼過程。而bytes
類型恰好有個decode()
方法,它是從比特流向字符串解碼的過程。除此之外,我們查看Python源碼會發現bytes
和str
擁有幾乎一模一樣的方法列表,最大的區別就是encode
和decode
。
從實質上來說,字符串在磁盤上的保存形式也是01的組合,也需要編碼解碼。
如果,上面的闡述還不能讓你搞清楚兩者的區別,那么記住下面兩幾句話:
-
在將字符串存入磁盤和從磁盤讀取字符串的過程中,Python自動地幫你完成了編碼和解碼的工作,你不需要關心它的過程。
-
使用
bytes
類型,實質上是告訴Python,不需要它幫你自動地完成編碼和解碼的工作,而是用戶自己手動進行,並指定編碼格式。 -
Python已經嚴格區分了
bytes
和str
兩種數據類型,你不能在需要bytes
類型參數的時候使用str
參數,反之亦然。這點在讀寫磁盤文件時容易碰到。