亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

徹徹底底地理解Python中的編碼問(wèn)題

 更新時(shí)間:2018年10月15日 10:04:46   作者:milter  
Python處理文本的功能非常強(qiáng)大,但是如果是初學(xué)者,沒(méi)有搞清楚python中的編碼機(jī)制,也經(jīng)常會(huì)遇到亂碼或者decode error。本文的目的是簡(jiǎn)明扼要地說(shuō)明python的編碼機(jī)制,并給出一些建議,需要的朋友可以參考下

Python處理文本的功能非常強(qiáng)大,但是如果是初學(xué)者,沒(méi)有搞清楚python中的編碼機(jī)制,也經(jīng)常會(huì)遇到亂碼或者decode error。本文的目的是簡(jiǎn)明扼要地說(shuō)明python的編碼機(jī)制,并給出一些建議。

問(wèn)題1:?jiǎn)栴}在哪里?

問(wèn)題是我們的靶子,心中沒(méi)有問(wèn)題去學(xué)習(xí)就會(huì)抓不住重點(diǎn)。

本文使用的編程環(huán)境是centos6.7,python2.7。我們?cè)趕hell中鍵入python以打開(kāi)python命令行,并鍵入如下兩句話:

 s = "中國(guó)zg"
 e = s.encode("utf-8")

現(xiàn)在的問(wèn)題是:這段代碼能運(yùn)行嗎?

答案是不能,會(huì)報(bào)如下的錯(cuò):

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

請(qǐng)留意一下錯(cuò)誤中說(shuō)明的0xe4,它是我們分析錯(cuò)誤的突破口。

相信很多人都遇到過(guò)這個(gè)錯(cuò)誤。那么新的問(wèn)題來(lái)了。

問(wèn)題2:Why?

要搞清楚原因,我們不妨認(rèn)真分析下這兩句話的執(zhí)行流程:

首先,我們通過(guò)鍵盤(pán)在python命令行解釋器中鍵入了 中國(guó)zg 并且給它加上了英文的雙引號(hào),然后又賦值給了變量s,看起來(lái)很稀松平常是不是?其實(shí)里面大有玄機(jī)。

當(dāng)我們通過(guò)鍵盤(pán)在程序中輸入字符時(shí),我們是通過(guò)操作系統(tǒng)完成這個(gè)功能的。我們?cè)谄聊簧峡吹降?中國(guó)zg 實(shí)際上是操作系統(tǒng)給我們?nèi)祟惖囊粋€(gè)反饋,告訴你:“嗨,哥們,你在程序中輸入了字符 中國(guó)zg ”

那操作系統(tǒng)給程序的反饋是什么呢?答案就是01串,這個(gè)01串是什么樣子,又是怎么生成的呢?

答案就是操作系統(tǒng)使用自己的默認(rèn)編碼方式,將中國(guó)zg進(jìn)行了編碼,并把編碼后的01串給了程序。

我們用的centos系統(tǒng)默認(rèn)的編碼是utf-8,所以,只要知道中國(guó)zg每個(gè)字符的utf-8的編碼就可以知道01串是什么了。

查詢后,可以獲得它們的編碼是(以16進(jìn)制和2進(jìn)制表示):

國(guó) z g
E4B8AD E59BBD 7A 67
11100101 10011011 10111101 11100101 10011011 10111101 01111010 01100111

現(xiàn)在我們知道操作系統(tǒng)傳給程序的01串長(zhǎng)什么樣子了。然后,程序會(huì)怎么處理它呢?

程序看到這個(gè)01串被雙引號(hào)包圍著,自然知道這個(gè)01串是一個(gè)字符串。然后這個(gè)字符串被賦值給了s。

到此,就是第一句的執(zhí)行邏輯。

現(xiàn)在繼續(xù)進(jìn)行第二句的執(zhí)行。

e = s.encode("utf-8")的意思是將字符串s用utf-8進(jìn)行編碼,并將編碼后的字符串賦值給e。問(wèn)題來(lái)了,程序現(xiàn)在知道s中的01串,還知道這個(gè)01串表示的是字符串,但這個(gè)字符串的編碼是什么呢?我們必須知道01串的現(xiàn)有編碼才能解析出里面的字符,也才能用新的編碼方式,如utf-8來(lái)重新編碼它。操作系統(tǒng)只給程序傳來(lái)了01串,并沒(méi)有告訴程序這個(gè)01串用的字符編碼是什么。

此時(shí),python程序就會(huì)用它自己默認(rèn)的編碼當(dāng)作s的編碼,進(jìn)而來(lái)識(shí)別s中的內(nèi)容。這個(gè)默認(rèn)的編碼是ASCII,所以,它會(huì)用ASCII來(lái)解釋這個(gè)01串,識(shí)別出字符串的內(nèi)容,再將這個(gè)字符串轉(zhuǎn)為utf-8編碼。

好了,程序碰到的第一個(gè)字節(jié)就是E4(11100101 ),傻眼! ASCII編碼中沒(méi)有這玩意兒,因?yàn)锳SCII編碼中字節(jié)第一位都是0。

怎么辦?

報(bào)錯(cuò)唄,于是我們就看到了上面的錯(cuò)誤。

錯(cuò)誤中的0xe4就是字符 “中” 的utf8編碼的第一個(gè)字節(jié)。

問(wèn)題3:How?

知道問(wèn)題出在哪里了,怎么解決這個(gè)問(wèn)題呢?

顯然,我們只要告訴程序,這個(gè)s中的01串的編碼是utf-8,程序就應(yīng)該能正確工作。

但這樣的解決方法有一個(gè)問(wèn)題,就是不夠通用。

假如我有個(gè)程序,它要讀取很多文本文件,每個(gè)文本文件的編碼都不一樣,豈不是針對(duì)每個(gè)讀進(jìn)來(lái)的文件都維護(hù)一個(gè)編碼信息?很繁瑣。

進(jìn)一步,如果這些文本文件的內(nèi)容還要做相互的比較連接之類的操作,編碼都不一致,豈不是更麻煩?

python是怎么聰明地解決這個(gè)問(wèn)題的呢?

很簡(jiǎn)單,就是decode!

decode的意思是說(shuō),你有一個(gè)字符串,并且你知道它的編碼,只要你用該編碼decode這個(gè)字符串,那么,python就會(huì)識(shí)別出里面的字符內(nèi)容,同時(shí),建一個(gè)int數(shù)組,將每個(gè)字符的unicode序號(hào)存進(jìn)去。

所有的字符串都這樣做,就可以確保在程序運(yùn)行過(guò)程中,各種來(lái)源獲得的字符串都有一樣的表示。它們就可以方便地進(jìn)行各種操作了。

上面說(shuō)的 int數(shù)組會(huì)被python封裝成一個(gè)對(duì)象,即unicode對(duì)象。

問(wèn)題4:如何搞定?

下面,我們?cè)趐ython命令行中輸入如下兩行代碼:

e = s.decode("utf-8")
isinstance(e,unicode)

程序的輸出是True,這說(shuō)明,decode后返回的e確實(shí)是一個(gè)unicode對(duì)象。

unicode在這里是一個(gè)類,是python里面的類。

e 被稱作unicode字符串,意思是說(shuō),它存的是字符的unicode序號(hào),并沒(méi)有使用任何編碼。

然后,我們就可以將e編碼成任意一種編碼,比如下面的操作都是可以的

e.encode("utf-8")
e.encode("gbk")

只要你選擇的編碼能夠?qū)中的字符進(jìn)行編碼即可,如果不能編碼,就會(huì)報(bào)錯(cuò)。

比如,如果你嘗試這樣:

e.encode("ascii")

由于ASCII并不能編碼 中國(guó) 這兩個(gè)字符,所以會(huì)爆出 encode error。

至此,我們已經(jīng)看到了兩種錯(cuò)誤,decode error 和encode error,并解決了它們。

問(wèn)題5:如何評(píng)價(jià)python的這種字符編碼處理方法?

首先,這樣的處理方法非常的簡(jiǎn)單。任何文本,只要它進(jìn)入程序時(shí)進(jìn)行一次decode,就會(huì)變成unicode對(duì)象,里面用int存著每個(gè)字符的unicode序號(hào)。只要在這個(gè)文本要輸出時(shí)再進(jìn)行一次encode,編碼成我們需要的編碼就可以了。

問(wèn)題是,所有的字符都用一個(gè)int來(lái)表示會(huì)不會(huì)太浪費(fèi)空間?畢竟,用ASCII編碼,英文的字符只要一個(gè)字節(jié)就可以了。

確實(shí)會(huì)費(fèi)點(diǎn)空間,但是現(xiàn)在的內(nèi)存都足夠大,而且我們只在程序內(nèi)部使用這種方式,當(dāng)字符串要寫(xiě)入文件或者通過(guò)網(wǎng)絡(luò)傳輸時(shí),我們都會(huì)進(jìn)行相應(yīng)的編碼的。

還有一個(gè)問(wèn)題,那些寫(xiě)死在程序中的字符串怎么辦?難道每次使用都要進(jìn)行一次decode?不同的操作系統(tǒng)默認(rèn)使用的編碼是不一樣的,當(dāng)我們?cè)趌inux下,通常需要用utf8做decode,在Windows下,通常需要用gbk做 decode。這樣,我們的代碼就只能在特定的平臺(tái)運(yùn)行。

python給我們提供了一個(gè)很簡(jiǎn)單的辦法,只要在字符串前面加一個(gè)u,它就會(huì)幫我們探測(cè)系統(tǒng)的編碼,并自動(dòng)完成decode。

問(wèn)題6:總結(jié)下,學(xué)到了什么?

本文用一個(gè)很常見(jiàn)的錯(cuò)誤為起點(diǎn),詳細(xì)分析了python中的編碼問(wèn)題。我們看到了python處理字符問(wèn)題的簡(jiǎn)單之處,也能夠理解為什么python有這么強(qiáng)大的文本處理功能。

測(cè)試題:看你是否真正理解了。

假設(shè)一臺(tái)linux上有一個(gè)文件a.txt,里面的內(nèi)容是"中文"兩個(gè)字符,編碼方式是utf-8。

現(xiàn)在,在python程序中寫(xiě)如下語(yǔ)句:

import codec
s=""
with codec.open("a.txt",encoding="utf-8") as f:
s=f.readline().strip()
with open("b.txt","w") as f:
f.write(s)

請(qǐng)問(wèn)這段代碼能執(zhí)行嗎?為什么?

答案:不能!

s底下的表示是unicode,寫(xiě)出時(shí)python會(huì)對(duì)其進(jìn)行編碼,默認(rèn)用的ascii編碼無(wú)法對(duì)"中文"兩個(gè)字符進(jìn)行編碼,所以會(huì)報(bào)錯(cuò)!

總結(jié)

以上所述是小編給大家介紹的徹徹底底地理解Python中的編碼問(wèn)題,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Python?中的嵌套字典推導(dǎo)的使用及優(yōu)勢(shì)

    Python?中的嵌套字典推導(dǎo)的使用及優(yōu)勢(shì)

    Python 字典推導(dǎo)是一個(gè)強(qiáng)大的工具,允許您從現(xiàn)有的字典創(chuàng)建新的字典,這篇文章主要介紹了Python中的嵌套字典推導(dǎo),將探索 Python 嵌套字典推導(dǎo)、它的使用以及在 Python 中使用它的優(yōu)勢(shì),需要的朋友可以參考下
    2023-05-05
  • Python tensorflow實(shí)現(xiàn)mnist手寫(xiě)數(shù)字識(shí)別示例【非卷積與卷積實(shí)現(xiàn)】

    Python tensorflow實(shí)現(xiàn)mnist手寫(xiě)數(shù)字識(shí)別示例【非卷積與卷積實(shí)現(xiàn)】

    這篇文章主要介紹了Python tensorflow實(shí)現(xiàn)mnist手寫(xiě)數(shù)字識(shí)別,結(jié)合實(shí)例形式分析了基于tensorflow模塊使用非卷積與卷積算法實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別的具體操作技巧,需要的朋友可以參考下
    2019-12-12
  • Django自定義分頁(yè)與bootstrap分頁(yè)結(jié)合

    Django自定義分頁(yè)與bootstrap分頁(yè)結(jié)合

    這篇文章主要為大家詳細(xì)介紹了Django自定義分頁(yè)與bootstrap分頁(yè)結(jié)合使用的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Python多線程編程之threading模塊詳解

    Python多線程編程之threading模塊詳解

    這篇文章主要介紹了Python多線程編程之threading模塊詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • python深度學(xué)習(xí)tensorflow1.0參數(shù)和特征提取

    python深度學(xué)習(xí)tensorflow1.0參數(shù)和特征提取

    這篇文章主要為大家介紹了python深度學(xué)習(xí)tensorflow1.0參數(shù)和特征提取,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Jupyter Notebook 基本操作快捷鍵方式

    Jupyter Notebook 基本操作快捷鍵方式

    這篇文章主要介紹了Jupyter Notebook 基本操作快捷鍵方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Python基于回溯法子集樹(shù)模板解決m著色問(wèn)題示例

    Python基于回溯法子集樹(shù)模板解決m著色問(wèn)題示例

    這篇文章主要介紹了Python基于回溯法子集樹(shù)模板解決m著色問(wèn)題,簡(jiǎn)單描述了m著色問(wèn)題并結(jié)合實(shí)例形式分析了Python使用回溯法子集樹(shù)模板解決m著色問(wèn)題的具體步驟與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2017-09-09
  • Python?Selenium如何切換瀏覽器的頁(yè)面

    Python?Selenium如何切換瀏覽器的頁(yè)面

    這篇文章主要介紹了Python?Selenium如何切換瀏覽器的頁(yè)面的相關(guān)資料,在使用Selenium進(jìn)行網(wǎng)頁(yè)測(cè)試時(shí),跳轉(zhuǎn)頁(yè)面后常會(huì)出現(xiàn)無(wú)法定位元素的問(wèn)題,解決這一問(wèn)題的關(guān)鍵是學(xué)會(huì)在多個(gè)瀏覽器標(biāo)簽頁(yè)或窗口間切換,需要的朋友可以參考下
    2024-10-10
  • Python數(shù)據(jù)結(jié)構(gòu)與算法中的棧詳解(2)

    Python數(shù)據(jù)結(jié)構(gòu)與算法中的棧詳解(2)

    這篇文章主要為大家詳細(xì)介紹了Python中的棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • python list使用示例 list中找連續(xù)的數(shù)字

    python list使用示例 list中找連續(xù)的數(shù)字

    這篇文章主要介紹了list中找連續(xù)的數(shù)字的示例,大家參考使用吧
    2014-01-01

最新評(píng)論