一步一步搞定Python3.6編碼問題
Python中的編碼問題很蛋疼,我們遇到這類問題有時候會使用下面幾個步驟處理該問題:
1:這麽低級問題,別問同事了太丟人,趕緊百度;
2:臥槽,出了一堆廣告,罵個娘,趕緊找相關解決問題方式;
3:尼瑪,終於搞定,原來這麽簡單,趕緊搞定其它工作,晚上回頭在查原因;
4:傻B單位每天加班,到家都11點了,趕緊洗洗睡了;等會,先來局王者農藥......
5:編碼問題早就忘了;
6:過了幾天又出現編碼錯誤,,從第1步開始重新來過。
今天我們就花一局王者農藥時間搞定Python3.6的編碼問題。
搞清楚編碼格式:
1)編碼格式:utf-8, gbk, gb2312, unicode...
計算機和編碼關系:計算機如何顯示打印文字:中文,英文等。計算機不能識別字符,那麽它如何顯示?
計算機可以讀取數據,於是我們前輩就弄一個字模,通過01標識把這個字符給他畫出來,然後使用一個二進制碼和這個字模對應起來,這樣,計算機就能根據這個二進制碼把這個字符顯示出來了。
計算機 -> 編碼 -> 字模點陣 ->顯示,打印等。
2)為什麽那麽多編碼格式?
計算機是美國人發明的,他們只需要使用英文字符和常用符號,於是ascii(256)就足夠了;
後來計算機普及了,中國人想讓處理漢字,日本人想讓他處理日文,阿拉伯人想讓他處理阿拉伯語,於是就有了各種編碼格式;比如gb2312,;但是gb2312表示一個字符需要2個字節,這樣表示一個英文字符有點浪費,於是大牛們整出了utf-8,utf-16等可變長編碼格式。
出現了太多的編碼格式,讓人蛋疼,於是大牛們同意規範,又整出了unicode編碼格式,支持所有的語言。
到這裏,可能明白編碼格式了。
3)編寫一個txt文件,內容為:"中國",他存儲的是“中國”這個漢子麽,還是??
1: 借助工具看一哈:
文件內容:中國
文件存儲內容:二進制數字:D6D0 B9FA
文件編碼格式:gbk
2:修改下軟件編碼格式:utf-8
亂碼有麽有。
為什麽亂碼?因為文字存儲編碼格式為gbk,我們指定軟件編碼格式utf-8,然後問題出現了:
軟件去utf-8的編碼表裏找不到D6D0 B9FA對應的字模,或者找錯了,所以會亂碼。
Python中編碼格式問題
1:Python內置存儲格式為unicode
2:字符流和字節流問題:
1)字符流:程序內部使用,不能直接保存文件;str類型;
2)字節流:保存文件,網絡傳輸;byte類型;
3:Python中的編碼格式轉換
#Python3.6 >>> s = ‘中國‘ >>> s.decode(‘utf-8‘) Traceback (most recent call last): File "<pyshell#21>", line 1, in <module> s.decode(‘utf-8‘) AttributeError: ‘str‘ object has no attribute ‘decode‘ >>> u8 = s.encode(‘utf-8‘) >>> u8 b‘\xe4\xb8\xad\xe5\x9b\xbd‘ >>> u8.encode(‘utf-8‘) Traceback (most recent call last): File "<pyshell#24>", line 1, in <module> u8.encode(‘utf-8‘) AttributeError: ‘bytes‘ object has no attribute ‘encode‘ >>> u8.decode(‘utf-8‘) ‘中國‘ >>>
python3.6版本中,s為unicode,是字符串類型,沒有decode方法,所以做解碼失敗;
u8是s使用utf-8編碼後的數據,沒有encode方法;
u8可以使用decode方法解碼成unicode,如果解碼格式為其它,我們可以看看結果:
>>> u8.decode(‘gbk‘) Traceback (most recent call last): File "<pyshell#27>", line 1, in <module> u8.decode(‘gbk‘) UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xad in position 2: illegal multibyte sequence
常見解碼錯誤:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xad in position 2:
原因:u8的編碼格式是utf-8,我們使用gbk去解碼,造成該錯誤。
編碼格式之間轉換:(gb2312,utf-8...)->unicode ->(gb2312,utf-8...);
unicode是中間的橋梁。
4:文件打開問題(環境:window下):
將一個文本文件存儲為utf-8編碼,
>>> f = open(‘readme.txt‘) >>> f.read() Traceback (most recent call last): File "<pyshell#35>", line 1, in <module> f.read() UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xbd in position 8: incomplete multibyte sequence
將文件打開,讀取的時候為什麽會有問題;
1)文件存儲形式字節,讀取的時候是字節,編碼格式為Utf-8
2)讀取文件時候,read方法會做一個解碼操作,但是他是什麽形式解碼呢?查看幫助文檔:
>>> help(open) Help on built-in function open in module io: open(file, mode=‘r‘, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) Open file and return a stream. Raise IOError upon failure. ..... >>> f <_io.TextIOWrapper name=‘readme.txt‘ mode=‘r‘ encoding=‘cp936‘>
這裏可以看到,f的編碼格式"cp936",這個和gbk是一樣的編碼格式,到這裏知道為啥會出錯了吧,文件存儲字節是utf-8編碼,解碼使用gbk方式,所以會出錯,在open的時候指定編碼格式utf-8再來一次試試:
>>> f = open(‘readme.txt‘, encoding=‘utf-8‘) >>> line = f.readline() >>> line ‘\ufeff中國‘ >>> print (line) 中國
讀取成功,"\ufeff"是window下utf-8文件編碼格式頭。到這裏我們就基本搞清楚常見的編碼問題了。
5:文件存儲問題:
一個栗子:
>>> f = open(‘test.txt‘, ‘w‘) >>> f.write(‘中國‘) >>> f.close()
傳的參數為字符流,但實際存儲為字節流,
>>> f = open(‘test.txt‘, ‘rb‘) >>> f.read() b‘\xd6\xd0\xb9\xfa‘
自己搞搞:使用utf-8方式打開test.txt, 然後讀取出現什麽問題?
好了到這裏,編碼基本就到這裏,如果還有不清楚的可以參考俺的視頻課程:
http://edu.51cto.com/course/8983.html,第二章內容。
另外,俺的水平有限,如果錯誤歡迎指正。
本文出自 “編程人生” 博客,請務必保留此出處http://huangyg.blog.51cto.com/1744433/1957295
一步一步搞定Python3.6編碼問題