Python字符集和字符編碼詳情
前言
這一次我們分析一下Python的字符串,首先字符串是一個(gè)變長(zhǎng)對(duì)象,因?yàn)椴煌L(zhǎng)度的字符串所占的內(nèi)存是不一樣的;但同時(shí)字符串又是一個(gè)不可變對(duì)象,因?yàn)橐坏﹦?chuàng)建就不可以再修改了。
而Python中的字符串是通過(guò)unicode來(lái)表示的,在底層對(duì)應(yīng)的結(jié)構(gòu)體是PyUnicodeObject。不過(guò)話說(shuō)回來(lái),為什么需要unicode呢?
首先計(jì)算機(jī)存儲(chǔ)的基本單位是字節(jié),由8個(gè)比特位組成,由于英文字母算上大小寫只有52個(gè),再加上若干字符,數(shù)量不會(huì)超過(guò)256個(gè),因此一個(gè)字節(jié)完全可以表示。但是隨著計(jì)算機(jī)的普及,越來(lái)越多的非英文字符出現(xiàn),導(dǎo)致一個(gè)字節(jié)已經(jīng)無(wú)法表示了。所以只能曲線救國(guó),對(duì)于一個(gè)字節(jié)無(wú)法表示的字符,使用多個(gè)字節(jié)表示
但是這樣會(huì)出現(xiàn)兩個(gè)問(wèn)題:
- 因?yàn)槊總€(gè)國(guó)家都有自己的字符編碼,所以不支持多國(guó)語(yǔ)言,例如中文的編碼不可以包含日文,否則就會(huì)造成亂碼;
- 沒(méi)有統(tǒng)一標(biāo)準(zhǔn),例如中文有GB2312、GBK、GB18030等多個(gè)標(biāo)準(zhǔn);
到這里我們先不繼續(xù)往下深入,我們先來(lái)理清楚一些概念。
字符集和字符編碼
估計(jì)有很多小伙伴搞不清這兩者的區(qū)別,我們先來(lái)解釋一下所謂的字符集和字符編碼是怎么一回事?
字符集:系統(tǒng)支持的所有字符組成的集合,像ASCII、GB2312、Big5、unicode都屬于字符集。只不過(guò)不同的字符集所能容納的字符個(gè)數(shù)不同,比如ASCII字符集中不包含中文,unicode則可以容納世界上的所有字符;
字符編碼:負(fù)責(zé)將每個(gè)字符轉(zhuǎn)換成一個(gè)或多個(gè)計(jì)算機(jī)可以接受的具體數(shù)字,該數(shù)字可以理解為編號(hào),因此字符編碼維護(hù)了字符和編號(hào)之間的對(duì)應(yīng)關(guān)系。而編碼也分為多種,比如ascii、gbk、utf-8等等,字符編碼不同,那么字符轉(zhuǎn)換之后的編號(hào)也不同,當(dāng)然能轉(zhuǎn)化的字符種類也不同。比如ASCII這種字符編碼,它就只能轉(zhuǎn)換ASCII字符。
當(dāng)然,ASCII比較特殊,它既是字符集、也是字符編碼。并且不管采用什么編碼,ASCII字符對(duì)應(yīng)的編號(hào)永遠(yuǎn)是相同的。
將字符串中的每一個(gè)字符轉(zhuǎn)成對(duì)應(yīng)的編號(hào),那么得到的就是字節(jié)序列(bytes對(duì)象),因?yàn)橛?jì)算機(jī)存儲(chǔ)和網(wǎng)絡(luò)通訊的基本單位都是字節(jié),所以字符串必須以字節(jié)序列的形式進(jìn)行存儲(chǔ)或傳輸。
因此字符串和字節(jié)序列在某種程度上是很相似的,字符串按照指定的編碼進(jìn)行encode即可得到字節(jié)序列,也就是將每個(gè)字符都轉(zhuǎn)成對(duì)應(yīng)的編號(hào);字節(jié)序列按照相同的編碼decode即可得到字符串,也就是根據(jù)編號(hào)找到對(duì)應(yīng)的字符。
比如我們寫了一段文本,然后在存儲(chǔ)的時(shí)候必須先進(jìn)行編碼,也就是將每一個(gè)字符都轉(zhuǎn)成一個(gè)或多個(gè)系統(tǒng)可以接受的數(shù)字、即對(duì)應(yīng)的編號(hào)之后,才可以進(jìn)行存儲(chǔ)。
s = "你好" # 編碼之后就是一串?dāng)?shù)字 print(s.encode("gbk")) # b'\xc4\xe3\xba\xc3'
假設(shè)文本中只有你好二字,在存儲(chǔ)的時(shí)候采用gbk進(jìn)行編碼,那么在讀取的時(shí)候也必須使用gbk進(jìn)行解碼,否則的話就會(huì)無(wú)法解析而報(bào)錯(cuò)。因?yàn)樽址幋a不同,字符對(duì)應(yīng)的編號(hào)也不同。
再比如每個(gè)國(guó)家都有自己的字符編碼,你在日本的一臺(tái)計(jì)算機(jī)上寫好的文件拿到中國(guó)的計(jì)算機(jī)上打開(kāi),很有可能出現(xiàn)亂碼。因?yàn)樽址幋a不同,字符和編號(hào)之間的對(duì)應(yīng)關(guān)系也不同,采用不同的字符編碼進(jìn)行解析肯定會(huì)出問(wèn)題。
但我們說(shuō),對(duì)于ASCII字符來(lái)說(shuō),由于不管采用哪一種編碼,它們得到的編號(hào)都是固定的。所以編碼對(duì)于ASCII字符來(lái)說(shuō),沒(méi)有任何影響。
s = "abc" print(s.encode("gbk")) # b'abc' print(s.encode("gbk").decode("utf-8")) # abc # 但如果是非ASCII字符,就不行了 try: s = "你好" s.encode("gbk").decode("utf-8") except UnicodeError as e: # 報(bào)錯(cuò)了,無(wú)法解析 print(e) # 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte
這里我們?cè)倩貞浺幌耣ytes對(duì)象,我們創(chuàng)建的時(shí)候可以采用字面量的方式,比如 b"abc",但是 b"憨"卻不可以。原因就是憨這個(gè)字符不是ASCII字符,那么采用不同的字符編碼,其對(duì)應(yīng)的編號(hào)是不同的,而這種方式Python又不知道我們使用哪一種編碼,所以不允許這么做,而是需要通過(guò)"憨".encode的方式手動(dòng)指定字符編碼。
但是對(duì)于 ASCII 字符而言,不管采用哪一種字符編碼,得到的編號(hào)都是一樣的, 所以Python針對(duì)ASCII字符則允許這種做法,比如b"abc"。并且我們看到,對(duì)于漢字來(lái)說(shuō),在編碼之后會(huì)對(duì)應(yīng)多個(gè)編號(hào),而每個(gè)編號(hào)占1字節(jié),因此不同的字符所占的大小可能不同。
小結(jié)
以上就是字符集和字符編碼,字符集就是字符組成的集合,不同字符集所能容納的字符數(shù)量是有限的。字符編碼是將字符轉(zhuǎn)成對(duì)應(yīng)的編號(hào),比如將一個(gè)字符串中的所有字符都轉(zhuǎn)成對(duì)應(yīng)的編號(hào)之后,就得到了字節(jié)序列。
當(dāng)然和字符集一樣,字符編碼能轉(zhuǎn)換的字符種類也是有限的,像漢字我們可以使用 gbk 編碼、utf-8 編碼,但是不能使用 ascii 編碼。
到此這篇關(guān)于Python字符集和字符編碼詳情的文章就介紹到這了,更多相關(guān)Python字符編碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python import導(dǎo)入上級(jí)目錄文件的方法
這篇文章主要介紹了Python import導(dǎo)入上級(jí)目錄文件,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01Python+opencv+pyaudio實(shí)現(xiàn)帶聲音屏幕錄制
今天小編就為大家分享一篇Python+opencv+pyaudio實(shí)現(xiàn)帶聲音屏幕錄制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12對(duì)python實(shí)現(xiàn)模板生成腳本的方法詳解
今天小編就為大家分享一篇對(duì)python實(shí)現(xiàn)模板生成腳本的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Python使用for實(shí)現(xiàn)無(wú)限循環(huán)的多種方式匯總
這篇文章主要介紹了Python使用for實(shí)現(xiàn)無(wú)限循環(huán)的多種方式匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Django Haystack 全文檢索與關(guān)鍵詞高亮的實(shí)現(xiàn)
這篇文章主要介紹了Django Haystack 全文檢索與關(guān)鍵詞高亮的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Tensorflow深度學(xué)習(xí)使用CNN分類英文文本
這篇文章主要為大家介紹了Tensorflow深度學(xué)習(xí)CNN實(shí)現(xiàn)英文文本分類示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11pytorch算子torch.arange在CPU?GPU?NPU中支持?jǐn)?shù)據(jù)類型格式
這篇文章主要為大家介紹了pytorch算子torch.arange在CPU?GPU?NPU支持?jǐn)?shù)據(jù)類型格式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09