字符串編碼在Python里邊是經(jīng)常會(huì)遇到的問(wèn)題,特別是寫文件以及網(wǎng)絡(luò)傳輸?shù)倪^(guò)程中,當(dāng)調(diào)用某些函數(shù)的時(shí)候經(jīng)常會(huì)遇到一些字符串編碼提示錯(cuò)誤,所以有必要弄清楚這些編碼到底在搞什么鬼。
我們都知道計(jì)算機(jī)只能處理數(shù)字,文本轉(zhuǎn)換為數(shù)字才能處理。計(jì)算機(jī)中8個(gè)bit作為一個(gè)字節(jié),所以一個(gè)字節(jié)能表示最大的數(shù)字就是255。計(jì)算機(jī)是美國(guó)人發(fā)明的,而英文中涉及的編碼并不多,一個(gè)字節(jié)可以表示所有字符了,所以ASCII(American national Standard Code for Information Interchange,美國(guó)國(guó)家標(biāo)準(zhǔn)信息交換碼)編碼就成為美國(guó)人的標(biāo)準(zhǔn)編碼。但是我們都知道中文的字符肯定不止255個(gè)漢字,使用ASCII編碼來(lái)處理中文顯然是不夠的,所以中國(guó)制定了GB2312編碼,用兩個(gè)字節(jié)表示一個(gè)漢字,碰到及其特殊的情況,還會(huì)用三個(gè)字節(jié)來(lái)表示一個(gè)漢字。GB2312還把ASCII包含進(jìn)去了。同理,日文,韓文等上百個(gè)國(guó)家為了解決這個(gè)問(wèn)題發(fā)展了一套自己的編碼,于是乎標(biāo)準(zhǔn)越來(lái)越多,如果出現(xiàn)多種語(yǔ)言混合顯示就一定會(huì)出現(xiàn)亂碼。那么針對(duì)這種編碼“亂象”,Unicode便應(yīng)運(yùn)而生了,其將所有語(yǔ)言統(tǒng)一到一套編碼規(guī)則里。
Unicode有許多種編碼,比如說(shuō)可以通過(guò)16個(gè)bit或者32個(gè)bit來(lái)把所有語(yǔ)言統(tǒng)一到一套編碼里。舉個(gè)栗子,字母A用ASCII編碼的十進(jìn)制為65,二進(jìn)制為0100 0001;漢字“中”已經(jīng)超出了ASCII編碼的范圍,用unicode編碼是20013,二進(jìn)制是01001110 00101101;A用unicode編碼只需要前面補(bǔ)0,二進(jìn)制是00000000 0100 0001??梢钥闯觯瑄nicode不僅解決了ASCII碼本身的編碼問(wèn)題,還解決了超出ASCII編碼范圍之外的其他國(guó)家字符編碼的統(tǒng)一問(wèn)題。
雖然unicode編碼能做到將不同國(guó)家的字符進(jìn)行統(tǒng)一,使得亂碼問(wèn)題得以解決,但是如果內(nèi)容全是英文unicode編碼比ASCII編碼需要多一倍的存儲(chǔ)空間,同時(shí)如果傳輸需要多一倍的傳輸。當(dāng)傳輸文件比較小的時(shí)候,內(nèi)存資源和網(wǎng)絡(luò)帶寬尚能承受,當(dāng)文件傳輸達(dá)到上TB的時(shí)候,如果 “硬”傳,則需要消耗的資源就不可小覷了。為了解決這個(gè)問(wèn)題,一種可變長(zhǎng)的編碼“utf-8”就應(yīng)運(yùn)而生了,把英文變長(zhǎng)1個(gè)字節(jié),漢字3個(gè)字節(jié),特別生僻的變成4-6個(gè)字節(jié),如果傳輸大量的英文,utf8的作用就很明顯了。
不過(guò)正是因?yàn)閡tf-8編碼的可變長(zhǎng),一會(huì)兒一個(gè)字符串是占用一個(gè)字節(jié),一會(huì)兒一個(gè)字符串占用兩個(gè)字節(jié),還有的占用三個(gè)及以上的字節(jié),導(dǎo)致在內(nèi)存中或者程序中變得不好琢磨。unicode編碼雖然占用內(nèi)存空間,但是在編程過(guò)程中或者在內(nèi)存處理的時(shí)候會(huì)比utf-8編碼更為簡(jiǎn)單,因?yàn)樗冀K保持一樣的長(zhǎng)度,一樣的長(zhǎng)度對(duì)于內(nèi)存和代碼來(lái)說(shuō),它的處理就會(huì)變得更加簡(jiǎn)單。所以u(píng)tf-8編碼在做網(wǎng)絡(luò)傳輸和文件保存的時(shí)候,將unicode編碼轉(zhuǎn)換成utf-8編碼,才能更好的發(fā)揮其作用;當(dāng)從文件中讀取數(shù)據(jù)到內(nèi)存中的時(shí)候,將utf-8編碼轉(zhuǎn)換為unicode編碼,亦為良策。
如上圖所示,當(dāng)需要在內(nèi)存中讀取文件的時(shí)候,此時(shí)將utf-8編碼的內(nèi)存轉(zhuǎn)換為unicode編碼,在內(nèi)存中進(jìn)行統(tǒng)一處理;當(dāng)需要保存文件的時(shí)候,出于空間和傳輸效率的考慮,此時(shí)將unicode編碼轉(zhuǎn)換為utf-8編碼。在Python中進(jìn)行讀取和保存文件的時(shí)候,必須要顯示的指定文件編碼,其余的事情就交給Python的相關(guān)庫(kù)去處理就可以了。
小伙伴們,了解了這些基礎(chǔ)知識(shí)之后,接下來(lái)對(duì)Python中的字符串編碼問(wèn)題的理解就輕松的多了。
聯(lián)系客服