Python的字符編碼
字符編碼
我在第一版的《零基礎學python》中,這個標題前面加了“坑爹”兩個字。在后來的實踐中,很多朋友都在網上問我關于編碼的事情。說明這的確是一個“坑”。
首先說明,在python2中,編碼問題的確有點麻煩。但是,python3就不用糾結于此了。但是,正如前面所說的原因,至少本教程還是用python2,所以,必須要搞清楚編碼。當然了,搞清楚,也不是壞事。
字符編碼,在編程中,是一個讓學習者比較郁悶的東西,比如一個str,如果都是英文,好說多了。但恰恰不是如此,中文是我們不得不用的。所以,哪怕是初學者,都要了解并能夠解決字符編碼問題。
>>> name = '老齊' >>> name '\xe8\x80\x81\xe9\xbd\x90'
在你的編程中,你遇到過上面的情形嗎?認識最下面一行打印出來的東西嗎?看人家英文,就好多了
>>> name = "qiwsir" >>> name 'qiwsir'
難道這是中文的錯嗎?看來投胎真的是一個技術活。是的,投胎是技術活,但上面的問題不是中文的錯。
encode和decode
歷史部分說完了,接下怎么講?比較麻煩了。因為不管怎么講,都不是三言兩語說清楚的。姑且從encode()和decode()兩個內置函數起吧。
codecs.encode(obj[, encoding[, errors]]):Encodes obj using the codec registered for encoding. codecs.decode(obj[, encoding[, errors]]):Decodes obj using the codec registered for encoding.
</blockquote>python2默認的編碼是ascii,通過encode可以將對象的編碼轉換為指定編碼格式(稱作“編碼”),而decode是這個過程的逆過程(稱作“解碼”)。
做一個實驗,才能理解:
>>> a = "中" >>> type(a) <type 'str'> >>> a '\xe4\xb8\xad' >>> len(a) 3>>> b = a.decode() >>> b u'\u4e2d' >>> type(b) <type 'unicode'> >>> len(b) 1</pre>
這個實驗不做之前,或許看官還不是很迷茫(因為不知道,知道的越多越迷茫),實驗做完了,自己也迷茫了。別急躁,對編碼問題的理解,要慢慢來,如果一時理解不了,也肯定理解不了,就先注意按照要求做,做著做著就豁然開朗了。
上面試驗中,變量a引用了一個字符串,所謂字符串(str),嚴格地將是字節串,它是經過編碼后的字節組成的序列。也就是你在上面的實驗中,看到的是“中”這個字在計算機中編碼之后的字節表示。(關于字節,看官可以google一下)。用len(a)來度量它的長度,它是由三個字節組成的。
然后通過decode函數,將字節串轉變為字符串,并且這個字符串是按照unicode編碼的。在unicode編碼中,一個漢字對應一個字符,這時候度量它的長度就是1.
反過來,一個unicode編碼的字符串,也可以轉換為字節串。
>>> c = b.encode('utf-8') >>> c '\xe4\xb8\xad' >>> type(c) <type 'str'> >>> c == a True關于編碼問題,先到這里,點到為止吧。因為再扯,還會扯出問題來。看官肯定感到不滿意,因為還沒有知其所以然。沒關系,請盡情google,即可解決。
python中如何避免中文是亂碼
這個問題是一個具有很強操作性的問題。我這里有一個經驗總結,分享一下,供參考:
首先,提倡使用utf-8編碼方案,因為它跨平臺不錯。
經驗一:在開頭聲明:
# -*- coding: utf-8 -*-有朋友問我-*-有什么作用,那個就是為了好看,愛美之心人皆有,更何況程序員?當然,也可以寫成:
# coding:utf-8經驗二:遇到字符(節)串,立刻轉化為unicode,不要用str(),直接使用unicode()
unicode_str = unicode('中文', encoding='utf-8') print unicode_str.encode('utf-8')經驗三:如果對文件操作,打開文件的時候,最好用codecs.open,替代open(這個后面會講到,先放在這里)
import codecs codecs.open('filename', encoding='utf8')我還收集了網上的一片文章,也挺好的,推薦給看官:Python2.x的中文顯示方法
最后告訴給我,如果用python3,坑爹的編碼問題就不煩惱了。