摘要:的字符串有兩種和,的字符串也有兩種和。不同字符的不同表現(xiàn),讓的和顯得撲朔迷離。在中,嚴(yán)格區(qū)分了和,不同類(lèi)型之間操作就會(huì)拋出的異常。和之間的轉(zhuǎn)換一圖勝千言和的相互轉(zhuǎn)換指的是具體的編碼規(guī)則的名稱(chēng),對(duì)于中文來(lái)說(shuō),它可以是這些值等等。
Python2的字符串有兩種:str 和 unicode,Python3的字符串也有兩種:str 和 bytes。Python2 的 str 相當(dāng)于 Python3 的bytes,而unicode相當(dāng)于Python3的str。
Python2里面的str和unicode是可以混用的,在都是英文字母的時(shí)候str和unicode沒(méi)有區(qū)別。而Python3 嚴(yán)格區(qū)分文本(str)和二進(jìn)制數(shù)據(jù)(bytes),文本總是unicode,用str類(lèi)型,二進(jìn)制數(shù)據(jù)則用bytes類(lèi)型表示,這樣嚴(yán)格的限制也讓我們對(duì)如何使用它們有了清晰的認(rèn)識(shí),這是很棒的。
Python2 和 Python3 的區(qū)別
通過(guò)以下代碼我們認(rèn)識(shí)以下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)Python3中:in () ----> 1 "編程" in u"編程" UnicodeDecodeError: "ascii" codec can"t decode byte 0xe7 in position 0: ordinal not in range(128)
In [1]: "a" == b"a" Out[1]: False In [2]: "a" in b"a" --------------------------------------------------------------------------- TypeError Traceback (most recent call last)in () ----> 1 "a" in b"a" TypeError: a bytes-like object is required, not "str"
以上代碼可以看到,Python2中str和unicode的在都是ascii碼時(shí)混用沒(méi)區(qū)別,因?yàn)閡nicode的ascii區(qū)域的值跟str的ascii是一樣的;而對(duì)應(yīng)非ascii區(qū)域(比如中文),二者又不一樣了,可以看到Python2拋出了UnicodeDecodeError的異常,相信這也是很多人處理文本時(shí)遇到過(guò)的錯(cuò)誤;‘編程’在str類(lèi)型時(shí)長(zhǎng)度是6,而在unicode時(shí)是2。不同字符的不同表現(xiàn),讓Python2的str和unicode顯得撲朔迷離。
在Python3中,嚴(yán)格區(qū)分了str和bytes,不同類(lèi)型之間操作就會(huì)拋出TypeError的異常。
上面用示例闡述了Python2和Python3中字符串的不同,下面主要講Python3中的字符串。
str和bytes之間的轉(zhuǎn)換
一圖勝千言:
str和bytes的相互轉(zhuǎn)換
str.encode(‘encoding’) -> bytes
bytes.decode(‘encoding’) -> str
encoding 指的是具體的編碼規(guī)則的名稱(chēng),對(duì)于中文來(lái)說(shuō),它可以是這些值: ‘utf-8’, ‘gb2312’, ‘gbk’, ‘big5’ 等等。
不知道你有沒(méi)有注意到上圖中str矩形要比bytes矩形短,表示同樣的內(nèi)容,str的長(zhǎng)度要小于或等于bytes的長(zhǎng)度,你可以考慮一下原因(參考Unicode、UTF-8的編碼規(guī)則)
下面看看具體代碼理解一下str和bytes的相互轉(zhuǎn)換:
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"Txe6x81xa4" In [21]: a == b Out[21]: False In [22]: c = a.encode("gbk") In [23]: c Out[23]: b"Txd0xf4" In [24]: b == c Out[24]: False In [25]: a == c Out[25]: False
上面str和bytes之間的轉(zhuǎn)換是針對(duì)文本內(nèi)容的,要是其它二進(jìn)制內(nèi)容(比如,圖片)時(shí),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)in () ----> 1 img.decode("utf8") UnicodeDecodeError: "utf-8" codec can"t decode byte 0xff in position 0: invalid start byte
因?yàn)閳D片中的二進(jìn)制數(shù)據(jù)不符合文本數(shù)據(jù)的UTF-8編碼規(guī)則。
上面獲得圖片數(shù)據(jù)時(shí),我們用到了open()來(lái)讀取文件,文件存儲(chǔ)的無(wú)非是文本和二進(jìn)制這兩種格式,讀寫(xiě)文件時(shí)也有分清楚編碼:
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)in () ----> 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
讀寫(xiě)二進(jìn)制數(shù)據(jù)(如圖片)時(shí),要加’rb’參數(shù),b代碼binary(二進(jìn)制)
讀寫(xiě)文本數(shù)據(jù)時(shí),一般加’b’,open()會(huì)自動(dòng)轉(zhuǎn)換bytes到str。
總結(jié)一下
Python3里面的str是在內(nèi)存中對(duì)文本數(shù)據(jù)進(jìn)行使用的,bytes是對(duì)二進(jìn)制數(shù)據(jù)使用的。
str可以encode為bytes,但是bytes不一定可以decode為str。實(shí)際上bytes.decode(‘latin1’)可以稱(chēng)為str,也就是說(shuō)decode使用的編碼決定了decode()的成敗,同樣的,UTF-8編碼的bytes字符串用GBK去decode()也會(huì)出錯(cuò)。
bytes一般來(lái)自網(wǎng)絡(luò)讀取的數(shù)據(jù)、從二進(jìn)制文件(圖片等)讀取的數(shù)據(jù)、以二進(jìn)制模式讀取的文本文件(.txt, .html, .py, .cpp等)
文章首發(fā)于猿人學(xué)網(wǎng)站:https://www.yuanrenxue.com/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/43645.html
摘要:一字典定義字典獲取元素這兩個(gè)的區(qū)別用在不存在的時(shí)候不會(huì)拋出設(shè)置當(dāng)不存在的時(shí)候返回的內(nèi)容增加和修改元素修改和增加元素的方法都是這個(gè)刪除元素刪除的同時(shí)返回刪除的內(nèi)容如果刪除不存在的會(huì)報(bào)這個(gè)時(shí)候就需要給定返回值這樣返回的就是不會(huì)報(bào)錯(cuò)誤從字典中隨機(jī) 一.字典: 定義字典:d = {}d = dict()d = {a:1, b:2} 1.獲取元素: d[a] d.get(a) >這兩個(gè)的區(qū)別,用...
Python的3??.0版本,常被稱(chēng)為Python 3000,或簡(jiǎn)稱(chēng)Py3k。相對(duì)于Python的早期版本,這是一個(gè)較大的升級(jí)。為了不帶入過(guò)多的累贅,Python 3.0在設(shè)計(jì)的時(shí)候沒(méi)有考慮向下相容。許多針對(duì)早期Python版本設(shè)計(jì)的程式都無(wú)法在Python 3.0上正常執(zhí)行。為了照顧現(xiàn)有程式,Python 2.6作為一個(gè)過(guò)渡版本,基本使用了Python 2.x的語(yǔ)法和庫(kù),同時(shí)考慮了向Python...
摘要:官方也宣布在停止對(duì)的維護(hù)。并且在很多面試過(guò)程中,面試官都會(huì)問(wèn)與的區(qū)別。的版本,常被稱(chēng)為,或簡(jiǎn)稱(chēng)。與部分地支持這種形式的語(yǔ)法。捕獲異常的語(yǔ)法由改為。在中,表示八進(jìn)制字面量的方式只有一種,就是。已經(jīng)支援新的模組。 前言 如果你是剛接觸 Python 的初學(xué)者,那你可能是直接學(xué)習(xí) Python 3.x 版本。對(duì)于 Python 2.x 的版本是不會(huì)有所接觸。官方也宣布在 2020 停止對(duì) P...
摘要:于是抽時(shí)間看了看以后各個(gè)版本的特性,做了一個(gè)總結(jié)。年和公開(kāi)版本發(fā)布,取名為。此后對(duì)應(yīng)版本就是,。發(fā)布,是一個(gè)重大版本更新。在此之后,就是每六個(gè)月發(fā)布一次新版本。以上和參考資料聊了一些關(guān)于的歷史,下面我們看看各個(gè)版本有那些新特性。 【這是 ZY 第 11 篇原創(chuàng)技術(shù)文章】 某天在網(wǎng)上閑逛,突然看到有篇介紹 Java 11 新特性的文章,頓時(shí)心里一驚,畢竟我對(duì)于 Java 的版本認(rèn)識(shí)...
摘要:認(rèn)為有極大的優(yōu)化空間,在字符串和整形操作上可以取得很好的優(yōu)化結(jié)果。的和方法返回迭代器,而之前的等函數(shù)都被廢棄。python有兩個(gè)主要的版本,python2 和 python3 ,但是python又不同于其他語(yǔ)言,向下兼容,python3是不向下兼容的,但是絕大多數(shù)組件和擴(kuò)展都是基于python2的,下面就來(lái)總結(jié)一下python2和python3的區(qū)別。 ? 1.性能? Py3.0運(yùn)...
閱讀 2749·2021-10-09 09:44
閱讀 3557·2019-08-30 15:54
閱讀 2168·2019-08-30 14:16
閱讀 2801·2019-08-30 13:09
閱讀 831·2019-08-30 13:08
閱讀 1291·2019-08-29 16:29
閱讀 1678·2019-08-26 13:57
閱讀 1934·2019-08-26 13:53