久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

《源碼探秘 CPython》19. 字符集和字符編碼

 古明地覺O_o 2022-12-08 發(fā)布于北京

楔子

這一次我們分析一下Python的字符串,首先字符串是一個(gè)變長對(duì)象,,因?yàn)椴煌L度的字符串所占的內(nèi)存是不一樣的,;但同時(shí)字符串又是一個(gè)不可變對(duì)象,,因?yàn)橐坏﹦?chuàng)建就不可以再修改了。

而Python中的字符串是通過unicode來表示的,,在底層對(duì)應(yīng)的結(jié)構(gòu)體是PyUnicodeObject,。不過話說回來,為什么需要unicode呢?

首先計(jì)算機(jī)存儲(chǔ)的基本單位是字節(jié),,由8個(gè)比特位組成,,由于英文字母算上大小寫只有52個(gè),再加上若干字符,,數(shù)量不會(huì)超過256個(gè),因此一個(gè)字節(jié)完全可以表示,。但是隨著計(jì)算機(jī)的普及,,越來越多的非英文字符出現(xiàn),導(dǎo)致一個(gè)字節(jié)已經(jīng)無法表示了,。所以只能曲線救國,,對(duì)于一個(gè)字節(jié)無法表示的字符,使用多個(gè)字節(jié)表示,。

但是這樣會(huì)出現(xiàn)兩個(gè)問題:

  • 因?yàn)槊總€(gè)國家都有自己的字符編碼,,所以不支持多國語言,例如中文的編碼不可以包含日文,,否則就會(huì)造成亂碼,;

  • 沒有統(tǒng)一標(biāo)準(zhǔn),例如中文有GB2312,、GBK,、GB18030等多個(gè)標(biāo)準(zhǔn);

到這里我們先不繼續(xù)往下深入,,我們先來理清楚一些概念,。

字符集和字符編碼

估計(jì)有很多小伙伴搞不清這兩者的區(qū)別,我們先來解釋一下所謂的字符集和字符編碼是怎么一回事,?

字符集:系統(tǒng)支持的所有字符組成的集合,,像ASCII、GB2312,、Big5,、unicode都屬于字符集。只不過不同的字符集所能容納的字符個(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ì)無法解析而報(bào)錯(cuò),。因?yàn)樽址幋a不同,字符對(duì)應(yīng)的編號(hào)也不同,。

再比如每個(gè)國家都有自己的字符編碼,,你在日本的一臺(tái)計(jì)算機(jī)上寫好的文件拿到中國的計(jì)算機(jī)上打開,很有可能出現(xiàn)亂碼。因?yàn)樽址幋a不同,,字符和編號(hào)之間的對(duì)應(yīng)關(guān)系也不同,,采用不同的字符編碼進(jìn)行解析肯定會(huì)出問題。

但我們說,,對(duì)于ASCII字符來說,,由于不管采用哪一種編碼,它們得到的編號(hào)都是固定的,。所以編碼對(duì)于ASCII字符來說,,沒有任何影響。

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ò)了,,無法解析 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又不知道我們使用哪一種編碼,,所以不允許這么做,而是需要通過"憨".encode的方式手動(dòng)指定字符編碼,。

但是對(duì)于 ASCII 字符而言,,不管采用哪一種字符編碼,得到的編號(hào)都是一樣的,, 所以Python針對(duì)ASCII字符則允許這種做法,,比如b"abc"。并且我們看到,,對(duì)于漢字來說,,在編碼之后會(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 編碼。

以上算是理清楚了一些概念,,顯然過于簡單了,,主要是為后面的內(nèi)容做鋪墊。那么下一篇,,就來從Python的角度分析字符串的存儲(chǔ)方式,。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多