前言
最近由于項目需要,需要讀取一個含有中文的txt文檔,完了還要保存文件。文檔之前是由base64編碼,導致所有漢字讀取顯示亂碼。項目組把base64廢棄之后,先后出現兩個錯誤:
如果對于ascii、unicode和utf-8還不了解的小伙伴,可以看之前的這篇文章關于字符串和編碼
那么必須對下面這三個概念有所了解:
- ascii只能表示數字、英文字母和一些特殊符號,不能表示漢字
- unicode和utf-8都可以表示漢字,unicode是固定長度,utf-8是可變長度
- 內存中存儲方式一般為unicode,而磁盤文件存儲方式一般為utf-8,因為utf-8可以節約存儲空間
那么python的默認編碼是什么?
1
2
3
4
5
6
7
8
|
>>> import sys >>> sys.getdefaultencoding() 'ascii' >>> reload (sys) <module 'sys' (built - in )> >>> sys.setdefaultencoding( 'utf-8' ) >>> sys.getdefaultencoding() 'utf-8' |
python的默認編碼是ascii,可以通過sys.setdefaultencoding('utf-8')
函數設置python的默認編碼。
python中可以通過encode和decode的方式改變數據的編碼,比如:
1
2
3
4
5
6
|
>>> u '漢字' u '\u6c49\u5b57' >>> u '漢字' .encode( 'utf-8' ) '\xe6\xb1\x89\xe5\xad\x97' >>> u '漢字' .encode( 'utf-8' ).decode( 'utf-8' ) u '\u6c49\u5b57' |
我們可以通過這兩個函數設置編碼。
那么,python中的str是什么類型?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
>>> import binascii >>> '漢字' '\xba\xba\xd7\xd6' >>> type ( '漢字' ) < type 'str' > >>> print binascii.b2a_hex( '漢字' ) babad7d6 >>> print binascii.b2a_hex(u '漢字' ) Traceback (most recent call last): File "<stdin>" , line 1 , in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0 - 1 : ordinal not in range ( 128 ) >>> print binascii.b2a_hex(u '漢字' .encode( 'utf-8' )) e6b189e5ad97 >>> print binascii.b2a_hex(u '漢字' .encode( 'gbk' )) babad7d6 |
binascii是將數據的二進制轉換成ascii,上面的解釋是:‘漢字'的類型是str,二進制是babad7d6,u‘漢字'是無法轉換成ascii,這樣就報出了開頭的第一個錯誤。解決辦法就是把它.encode(‘utf-8')成str類型。因為我命令行是windows默認的GBK編碼,所有u'漢字'.encode(‘gbk')
的時候,輸出結果和‘漢字'結果一樣。
總結一下,python的str實際上是unicode的一種,python的默認編碼是ascii,對于非ascii轉成ascii的時候都會報錯,牢記下面的規則:
- unicode => encode(‘合適的編碼') => str
- str => decode(‘合適的編碼') => unicode
還有一種簡單的方式,就是在文件頭設置編碼,可以省去很多麻煩:
1
2
3
|
import sys reloads(sys) sys.setdefaultencoding( 'utf-8' ) |
對于第二個問題,是在文件讀取的時候出的錯。utf-8的文件有bom和無bom兩種方式,兩者的差別好像在bom文件比無bom文件多了一個頭,導致以utf-8方式讀文件時報錯,我先前曾嘗試讀文件的時候先對有無bom進行判斷,跳過bom文件的頭,后來失敗了,真尷尬~~。
還得上google求助大神,具體的操作方法就是使用codecs庫來讀文件(我猜這個庫就是對文件的頭進行檢測)。
1
2
|
import codecs codecs. open (file_name, "r" ,encoding = 'utf-8' , errors = 'ignore' ) |
對于編碼問題,一定要懂得ascii、unicode和utf-8工作原理。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
原文鏈接:http://yuren.space/blog/2016/07/31/python如何解決漢字編碼問題/