python數(shù)據(jù)類型bytes?和?bytearray的使用與區(qū)別
bytes 和 bytearray
bytes 和 bytearray 都是二進(jìn)制世界的成員,用二進(jìn)制的方式去理解才能看清他的本質(zhì)。
理解bytes 和 bytearray
0 和 1 是計(jì)算機(jī)工作的根本,單個(gè)的0和1只能表達(dá)兩種狀態(tài),無(wú)法滿足我們復(fù)雜的計(jì)算,于是計(jì)算機(jī)使用了8位即一個(gè)byte作為一個(gè)儲(chǔ)存的基本單位。
byte 由 8bit 組成,例如 0000 0001 , 也可以表示為16進(jìn)制的形式:0x01, 0x為固定前綴,表示該數(shù)使用16進(jìn)制表示方式,此外0o前綴為8進(jìn)制,0b為二進(jìn)制形式,以此區(qū)分。bytes 從字面上理解是byte 的復(fù)數(shù), 也就是多個(gè)byte組成的序列。這一點(diǎn)與字符串與字符的關(guān)系類似。
于是,我們可以這樣理解,字符串是由一個(gè)個(gè)字符順序儲(chǔ)存組成的序列,其中每個(gè)元素為一個(gè)字符。bytes 是由一個(gè)個(gè)byte組成的序列,每一個(gè)元素是一個(gè)byte。
bytearray是一個(gè)由byte為元素組成的array,其中每一個(gè)元素為一個(gè)byte。在python官方文檔中,作者簡(jiǎn)單的定義了這兩個(gè)類型。翻譯為
bytes:可以看作是一組二進(jìn)制數(shù)值(0-255) 的 str 序列bytearray :可以看作是一組二進(jìn)制數(shù)值(0-255) 的 list 序列
python中值的表示
在計(jì)算機(jī)中表示數(shù)有多種表示方式,普通的表示方式就是10進(jìn)制的數(shù)值表示方法,例如a=10,此外還有8進(jìn)制,16進(jìn)制,2進(jìn)制的表示方式,分別使用前綴0o和0x和0b表示。
a = 97 a = 0b01100001 a = 0x61 a = 0o301
使用上面4種方式定義的值均為十進(jìn)制數(shù)97,也就是上面四種方式是等價(jià)得,只是使用不同的進(jìn)制表示同一個(gè)值。
除了使用數(shù)值可以有不同的表示方式外,還可以使用字節(jié)的方式來(lái)定義一個(gè)值,而字節(jié)該如何書(shū)寫(xiě)?python使用了一個(gè)特殊字符串來(lái)表示字節(jié),這個(gè)特殊字符可以使用前綴\x,\o, \b和\ 表示,分別表示16,8,2,10進(jìn)制的表示方式,特殊字符后是對(duì)應(yīng)的進(jìn)制表示值。示例
a = "a" a = "\b01100001" a = "\x61" a = "\o301"
同樣得,這樣得四種方式是等價(jià)得,a變量的值均為"a"。以上是單字節(jié)的字符的表示,多字節(jié)字符或者是一個(gè)字符串同樣可以如此定義。
# 使用encode查看一下中國(guó)的二進(jìn)制編碼為 str.encode("中國(guó)") # ==> b'\xe4\xb8\xad\xe5\x9b\xbd',前綴 b表示該值的類型為bytes,區(qū)別于字符串的表示 # 因此,我們可以使用這個(gè)字節(jié)表示來(lái)定義“中國(guó)” a = '\xe4b8ade59bbd' # 或者 '\xe4\xb8\xad\xe5\x9b\xbd',兩種方式均可 # 其8進(jìn)制可以如此計(jì)算 num = int.from_bytes(a, "big") # 將這段字符串轉(zhuǎn)化為內(nèi)存等值的數(shù)值 print(oct(num)) # 打印該數(shù)值的8進(jìn)制表示,結(jié)果為字符串類型。在該字符串加上\o前綴即可 # 最后打印結(jié)果 print(a) # ==> "中國(guó)" # 再假如我們需要定義一個(gè)字符串a(chǎn)bc,可以使用下面的方式 a = "abc" a = "\x616263" # 由于abc的ascii碼分別為 0x61 62 63 a = "\o301302303" # 由于abc的ascii碼分別為 0o301 302 303 a = "\979899" # 由于abc的ascii碼分別為 979899
進(jìn)制轉(zhuǎn)換
字節(jié),數(shù)值,字符等類型可以使用下面的方式進(jìn)行轉(zhuǎn)化。還包括值得不同進(jìn)制表示,字符串得不同進(jìn)制表示,示例:
# 內(nèi)置函數(shù) chr(97) # ==> "a" ord("a") # ==> 97 # 將一個(gè)10進(jìn)制數(shù),轉(zhuǎn)化為其他進(jìn)制的數(shù)的字符串表示得內(nèi)置函數(shù),注意,結(jié)果都是字符串,而不是對(duì)應(yīng)進(jìn)制的數(shù)值 bin(97) # ==> '0x61' oct(97) # 8進(jìn)制字符 '0o301' hex(97) # 2進(jìn)制字符 '0b01100001' # 也可使用format完成 #帶前綴 0x format(97,"#x") # ==> '0x61' format(97,"#o") # 8進(jìn)制字符 '0o301' format(97,"#b") # 2進(jìn)制字符 '0b01100001' #不帶前綴 format(97,"X") # ==> '61' format(97,"o") # ==> '301' format(97,"b") # ==> '01100001' # 3.6+版本使用方法 # f'{255:X}' 和 f'{255:#X}' ===> " FF " 和 "0xFF" # 使用c 風(fēng)格得表示 "%x"%10 # ==> 'a' "%o"%10 # ==> '12' # 帶前綴 "%#x"%10 # ==> '0xa' "%#o"%10 # ==> '0o12'
將一個(gè)字節(jié)或者字符或者字符串轉(zhuǎn)化為值類型可以使用如下的方式。
ord("a") # ==> 97 int.from_bytes(b"a", "big") # 97 類型為int,指定大端模式(小地址存多字節(jié)高位) # 以下兩種形式等價(jià) int.from_bytes(b"abc", "big") # ==> 得到三字節(jié)長(zhǎng)度的數(shù)值 int.from_bytes(bytes("abc"), "big") #
bytes類型
將一個(gè)str 轉(zhuǎn)化為 bytes 的本質(zhì)是將str中的每個(gè)字符轉(zhuǎn)化為該字符的二進(jìn)制編碼形式。例如 a 的二進(jìn)制為 0x65。
# 將字符串a(chǎn)bc 中每一個(gè)字符轉(zhuǎn)化為二進(jìn)制編碼形式就是bytes類型 s = "abc" bs1 = bytes("abc") # bytes()第一個(gè)參數(shù)為一個(gè)可迭代對(duì)象,將每一個(gè)元素轉(zhuǎn)為二進(jìn)制的表示方式 print(s) # 'abc' print(bs1) # b'abc' python檢測(cè)到這個(gè)二進(jìn)制序列可以使用字符abc表示,但是為了區(qū)別于abc的字符串,所以使用 b'abc',只是給人看的一種表示結(jié)果。實(shí)際的值應(yīng)該是一個(gè)個(gè)字節(jié)。 # 我們看一下單個(gè)元素 print(s[0]) # 'a' print(bs1[0]) # 97 而不是 b'a',對(duì)于單個(gè)字節(jié)0x61, python使用了十進(jìn)制數(shù)97表示
二進(jìn)制類型bytes使用b'abc'的表示方式,只是嘗試將這個(gè)序列中的元素翻譯為人類可以看懂的形式,實(shí)際在變量?jī)?nèi)存中儲(chǔ)存的為一個(gè)個(gè)二進(jìn)制字節(jié)0x61 0x62 0x63,這樣的三個(gè)字節(jié)可以根據(jù)數(shù)據(jù)類型的不同翻譯成不同的結(jié)果。
b2 = bytes( [97,98,99] ) print(b2) # ==> b'abc'
這就對(duì)上面結(jié)論最佳證明,出現(xiàn)該結(jié)果的原因是,python中的列表 [97, 98, 99] 在內(nèi)存中二進(jìn)制儲(chǔ)存和字符串a(chǎn)bc儲(chǔ)存的值是相同的,所以使用python來(lái)展示這段內(nèi)存時(shí),它使用b'abc'的方式進(jìn)行展示。
bytes類型轉(zhuǎn)化
字符串轉(zhuǎn)bytes類型
# 將返回 bytes 類型 b" abc ", 可以添加encoding參數(shù)指定字符串的編碼方式 bs1 = bytes("abc","utf-8") # 可以使用字符的16進(jìn)制字符表達(dá)形式 bs2 = bytes('\x61\x62\x63',"utf-8") # 直接對(duì)字符進(jìn)行編碼成二進(jìn)制形式 bs2 = "abc".encode() # 16進(jìn)制字符轉(zhuǎn)為bytes類型 b1 = bytes.fromhex("61 62 63") # ==> b"abc" "61,62"是兩個(gè)16進(jìn)制數(shù)組合,單個(gè)值不能超過(guò) 7F也就是不能超過(guò)127 ,否則無(wú)法對(duì)應(yīng)ASCII表中的字符 b1.hex() # ===> '616263' ASCII碼中abc字符對(duì)應(yīng)的16進(jìn)制數(shù)組成的字符串,上面函數(shù)的逆運(yùn)算。
數(shù)值轉(zhuǎn)化為bytes類型
想要使用數(shù)值來(lái)定義一個(gè)不能直接使用 bytes(97) 的方式來(lái)定義,這不會(huì)在內(nèi)存中儲(chǔ)存一個(gè)二進(jìn)制的 97,而是會(huì)開(kāi)辟97個(gè)字節(jié),每個(gè)字節(jié)的值為0x00。這是需要注意的一點(diǎn),如果想要儲(chǔ)存一個(gè)97,可以使用列表來(lái)實(shí)現(xiàn)。
# 傳入數(shù)值類型可迭代對(duì)象 b1 = bytes(range(97,100)) # ==> b'abc' b2 = bytes([97,98,99]) # ==> b'abc' b3 = bytes([97]) # ==> b'a' # 直接傳入10進(jìn)制數(shù)值對(duì)象而不是可迭代對(duì)象,將會(huì)生成對(duì)應(yīng)數(shù)值字節(jié)的空bytes b4 = bytes(3) # b'\x00\x00\x00' 三個(gè)空字符的 bytes # 通過(guò)數(shù)值轉(zhuǎn)化將8進(jìn)制,16進(jìn)制數(shù)字 生成bytes對(duì)象 b5 = bytes([int("61",16)]) #16進(jìn)制61 == > 10 進(jìn)制 ==> bytes ==> b"a" (使用字符a表示) b6 = bytes([int("61", 8)]) # 8進(jìn)制61 == > 10 進(jìn)制 ==> bytes ==> b"1" (使用字符1表示) # 也可利用bytes 對(duì)象轉(zhuǎn)化為 10 進(jìn)制 數(shù)值 num = int.from_bytes(b"abc","big") # "abc"對(duì)應(yīng)的三個(gè)字節(jié)拼接在一起作為一個(gè)二進(jìn)制數(shù),并計(jì)算為10進(jìn)制數(shù)輸出 print(num) # ===> 6382179
以上是將數(shù)值和字符串轉(zhuǎn)化為 字節(jié)類型,這是常用的類型轉(zhuǎn)化方式,同樣的,也可以將字節(jié)轉(zhuǎn)化為字符或者值的類型。使用以下的方法即可
bytes轉(zhuǎn)數(shù)值
bytes類型轉(zhuǎn)化為 值類型使用 數(shù)值使用 int的一個(gè)類方法from_bytes即可,示例:
num = int.from_bytes(b“abc”, "big") # 將這個(gè)bytes對(duì)象轉(zhuǎn)化為內(nèi)存等值的數(shù)值
bytes的方法
bytes對(duì)象的方法和字符串的方法基本一致,可以進(jìn)行字符串的幾乎所有操作,例如字符串的replace,split,partation等操作,唯一需要區(qū)別的是。字符串的操作操作的對(duì)象是一個(gè)字符串或者單個(gè)字符,而bytes對(duì)象操作的是一個(gè)bytes二進(jìn)制字節(jié),例如進(jìn)行字符串替換時(shí):
"abc".replace("a", "x") # 將字符a 替換為 x # 而在bytes對(duì)象 b"abc".replace(b"a", b"x") # 無(wú)論是參數(shù)中的對(duì)象還是對(duì)象本身都是bytes類型,有b“”前綴標(biāo)識(shí)
其他方法類比于str的方法,并結(jié)合官方文檔即可。
bytearray
bytearray類似于中的list數(shù)據(jù)類型,bytearray中的每一個(gè)元素始終為一個(gè)字節(jié)值,也就是 0x00 - 0xff 區(qū)間的一個(gè)值,如果不在該范圍內(nèi)的值,在指定了編碼方式的情況下可以按照字節(jié)遍歷
初始化一個(gè)bytearray對(duì)象。同樣需要一個(gè)可迭代對(duì)象作為參數(shù),將會(huì)按照字節(jié)遍歷整個(gè)可迭代對(duì)象,有以下的方式
bytearray("abc", encoding="utf-8") # abc字符串使用utf-8的方式編碼為字節(jié),每個(gè)字節(jié)作為bytearray對(duì)象的一個(gè)元素儲(chǔ)存即可。 bytearray(b"abc") # 也可以使用bytes 類型,而使用bytes類型就沒(méi)有編碼一說(shuō)了 bytearray([97, 98, 99]) # 使用可迭代對(duì)象,內(nèi)部元素為一個(gè)一個(gè)0-255的數(shù)值類型。 ba1 = bytearray(range(97,103)) # 可迭代當(dāng)然包括range對(duì)象
ba1 # bytearay對(duì)象,==> bytearray(b"abcdef") ba1[0] # ==> 97 (integer) ba1[1:4] # 切片 ==> bytearray(b'bcd') # 賦值,可變 bytearray ba[ 4 ] = 122 # 122整型對(duì)應(yīng)字符"z", ==> b"e" --> b"z" ba # bytearray(b"abcdzf" ) ba1[1:4] = b"xyz" # 切片賦值,替換ba1[1:4]的內(nèi)容, 只有bytes 或bytearray 序列可賦值
bytes和bytearray類型之間可以直接進(jìn)行轉(zhuǎn)化,bytes()中可以傳入一個(gè)bytearray對(duì)象作為參數(shù),并且不存在編碼問(wèn)題,因?yàn)閮蓚€(gè)類型都是一個(gè)二進(jìn)制的序列。
python在展示bytearray對(duì)象,使用的是bytesarray(b"abc") 的方式,其實(shí),不妨理解為 bytearray( [ b"a", b"b", b"c" ] ) 的形式。也就是每個(gè)元素為字節(jié)列表。所以byteaarray實(shí)現(xiàn)了和列表對(duì)象的方法,并且可以進(jìn)行元素的替換,也就是與列表相同,他是一個(gè)可變類型的對(duì)象。而bytes 與字符串都是不可變的,無(wú)法對(duì)單個(gè)元素進(jìn)行替換,對(duì)象一旦產(chǎn)生將不可變。如果需要改變,需要新建一個(gè)新的對(duì)象。
bytearray的方法
類似與 列表對(duì)象,可以進(jìn)行切片,append, extend,insert等操作,同樣的,由于內(nèi)部的元素都是一個(gè)個(gè)字節(jié)對(duì)象,對(duì)單個(gè)元素操作時(shí)只能操作單字節(jié)的對(duì)象,而執(zhí)行extend這類處理可迭代對(duì)象方法,也要求可迭代對(duì)象內(nèi)部的所有元素為單字節(jié)對(duì)象。單字節(jié)對(duì)象,可以是 b"a"類似的單字節(jié)對(duì)象 或 0-255的數(shù)值。因?yàn)橐粋€(gè)字節(jié)只能儲(chǔ)存256中狀態(tài)。以下是幾個(gè)簡(jiǎn)單的示例
a = bytearray(b"abc") a.append(100) print(a) # bytearray(b"abcd") a.append(b"e") print(a) # bytearray(b"abcde") a.extend(a) print(a) # bytearray(b"abcdeabcde") a.insert(0, b"A") print(a) # bytearray(b"Aabcdeabcde") bytes(a) # b"Aabcdeabcde"
到此這篇關(guān)于python數(shù)據(jù)類型bytes 和 bytearray的使用與區(qū)別的文章就介紹到這了,更多相關(guān)python bytes 和 bytearray內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3爬蟲(chóng)之設(shè)計(jì)簽名小程序
這篇文章主要為大家詳細(xì)介紹了python3爬蟲(chóng)之寫(xiě)為朋友設(shè)計(jì)簽名的小程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06使用Python實(shí)現(xiàn)Oracle數(shù)據(jù)庫(kù)自動(dòng)巡檢程序
這篇文章主要為大家詳細(xì)介紹了如何創(chuàng)建一個(gè)Oracle數(shù)據(jù)庫(kù)自動(dòng)巡檢程序,以確保數(shù)據(jù)庫(kù)的順暢運(yùn)行,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01PyQt5+pycharm開(kāi)發(fā)環(huán)境搭建的實(shí)現(xiàn)步驟(圖文)
本文針對(duì)創(chuàng)建PyQt運(yùn)行環(huán)境+PyCharm開(kāi)發(fā)環(huán)境的過(guò)程進(jìn)行記錄,文中通過(guò)圖片示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Python實(shí)現(xiàn)PDF轉(zhuǎn)Word的方法詳解
由于PDF的文件大多都是只讀文件,有時(shí)候?yàn)榱藵M足可以編輯的需要通??梢詫DF文件直接轉(zhuǎn)換成Word文件進(jìn)行操作。本文為大家整理了一些實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2023-02-02Python內(nèi)建類型str源碼學(xué)習(xí)
這篇文章主要為大家介紹了Python內(nèi)建類型str的源碼學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法
今天小編就為大家分享一篇python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06解決Djang2.0.1中的reverse導(dǎo)入失敗的問(wèn)題
今天小編就為大家分享一篇解決Djang2.0.1中的reverse導(dǎo)入失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08Python操作Word批量生成合同的實(shí)現(xiàn)示例
這篇文章主要介紹了Python操作Word批量生成合同的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08利用python+request通過(guò)接口實(shí)現(xiàn)人員通行記錄上傳功能
這篇文章主要介紹了利用python+request通過(guò)接口實(shí)現(xiàn)人員通行記錄上傳功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01