編碼與解碼
對(duì)于我這樣的新手來說python2.x的編碼解碼問題真是個(gè)坑晴弃,什么decode,encode或油,好亂好亂寞忿,怎么辦呢,還是得自己搞懂的顶岸,這個(gè)世界你能靠的只有自己腔彰。
查了好多資料書籍,下面我試著來解釋一下辖佣,有可能有些偏差霹抛,但是會(huì)好理解一點(diǎn):
當(dāng)我們要向?qū)Ψ奖磉_(dá)某種意思的時(shí)候,就會(huì)用文字(當(dāng)然有其他方法)寫下來卷谈,當(dāng)對(duì)方看到文字的時(shí)候杯拐,就會(huì)明白我們要表達(dá)的意思。
把要表達(dá)的意思寫下來就是編碼世蔗,對(duì)方看到文字后端逼,會(huì)把通過眼睛接受的文字翻譯成意思,然后就明白了要表達(dá)的東西污淋,這就是解碼
對(duì)應(yīng)到Python中顶滩,“意思”就是unicode,文字就是str寸爆,因?yàn)槲淖钟兄形幕寤觯⑽模靼嘌勒Z等等而昨,所以str就會(huì)有utf-8,ascii等找田,
因此unicode通過encode就會(huì)變成str歌憨,str通過decode就會(huì)變成unicode,一般我們以“utf-8”編碼:unicode.encode('utf-8'),解碼:str.decode('utf-8')
那為什么我們經(jīng)常會(huì)遇到UnicodeEncodError:'ascii'code can't encode characters in position...呢:
這一般是發(fā)生在有中文的情況下墩衙,原因是當(dāng)需要對(duì)str類型的字符串進(jìn)行解碼操作時(shí)务嫡,python會(huì)自動(dòng)將其解碼為unicode甲抖,而默認(rèn)采用的是ascii來解碼,舉個(gè)例子:
>>>a = u'hello' + 'ysf'
>>>a
u'helloysf'
這是在終端輸入的代碼,其中u‘hello’是unicode類型心铃,‘ysf’是str類型准谚,但是進(jìn)行python在處理u'hello' + 'ysf'時(shí)卻沒有報(bào)錯(cuò),最后還返回了u'helloysf'去扣,這是為什么呢柱衔?原因就在于python內(nèi)部先做了一步‘ysf’.decode('ascii'),將str類型解碼成了unicode類型,這在沒有中文的情況下是沒錯(cuò)的愉棱,但是當(dāng)有中文的時(shí)候唆铐,就有問題了,如下:
>>>a = u'hello' + '中文'
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
這是python在內(nèi)部進(jìn)行‘中文’.decode(‘a(chǎn)scii’)解碼時(shí)出錯(cuò)了奔滑,因?yàn)閍scii編碼不包含中文艾岂,因此無法解碼。按照如下方法改就不出錯(cuò)了
>>>a = u'hello' + '中文'.decode('utf-8')
>>>a
u'hello\u4e2d\u6587'
或者把系統(tǒng)默認(rèn)編碼方式改為‘utf-8’,如下朋其,也就不會(huì)出錯(cuò)了
>>>import sys
>>>reload(sys)
<module 'sys' (built-in)>
>>>sys.setdefaultencoding('utf-8')
>>>a = u'hello' + '中文'
>>>a
u'hello\u4e2d\u6587'
最后在提一下王浴,當(dāng)源代碼寫在腳本文件中時(shí),我們一般會(huì)用# -- coding:utf-8 --去申明梅猿,而且要保存為utf-8編碼氓辣,這樣子Python解釋器會(huì)按照‘utf-8’方式讀取源代碼,讀取后粒没,會(huì)轉(zhuǎn)換為Unicode字符到內(nèi)存里筛婉,編輯完成后,保存時(shí)在轉(zhuǎn)換為‘utf-8’癞松,因此如果要寫入文件中爽撒,就要用encode(‘utf-8’)編碼成utf-8類型。