無論學(xué)習(xí)什么程序語言,字符串這種數(shù)據(jù)類型總是著有非常重要。然而最近在學(xué)習(xí)python這門語言,想要顯示中文,總是出現(xiàn)各種亂碼。于是在網(wǎng)上查了很多資料,各說紛紜,我也嘗試了許多的方法,有時(shí)候可以正常顯示,有時(shí)候確實(shí)亂碼,讓我摸不著頭腦。于是自己利用python讀寫中文的文本文件來嘗試去摸索python中的中文編碼問題。比較幸運(yùn)的是,最后能夠正常的讀取出文本里面的中文數(shù)據(jù)并且顯示,而且還能將中文的結(jié)果數(shù)據(jù)寫入文本文件中。但是本文僅僅只是總結(jié)處理中文亂碼問題的小結(jié),并沒有將其編碼的原理弄透。那么,下面就讓我們開始吧。
1、首先得建立一個(gè)文本文件(編碼方式是ascii),文本文件的內(nèi)容如下:
編號,雨量,站點(diǎn)位置
1,10.2,南京
2,45,北京
3,78,上海
2、給這個(gè)文件文件的每一行建立一個(gè)數(shù)據(jù)層也就是建立儲存記錄的類
class Rain: def __init__(self,id,acc,site): self.id=id self.acc=acc self.site=site
首先需要建立一個(gè)py文件去著手寫我們的代碼。創(chuàng)建我的py文件之后我還什么代碼都沒寫,僅僅只是寫了兩行注釋之后,保存一下,就發(fā)現(xiàn)下面的Console結(jié)果框就出來了錯(cuò)誤。
代碼截圖如下:

原因分析:
原來Python的源代碼默認(rèn)的編碼是ascii編碼,而我的源代碼文件中的注釋含有中文,只是ascii編碼所不能表達(dá)的字符,固然被python解釋器解釋的時(shí)候會出現(xiàn)如下錯(cuò)誤。
解決方案:
只需要在文件的第一或者第二行,也只能是第一,第二行加上如下代碼 :
#coding:utf-8
這行代碼的意思是,讓解釋器用utf-8的方式去解釋源代碼文件。
2、錯(cuò)誤二
建立好一個(gè)py文件之后就要讀取文本里面的文件,代碼如下:
f=open("raindata.txt","r")f.readline()#第一行是列,可以將文件移到第二行開始處for line in f: PRint line
結(jié)果出現(xiàn)的結(jié)果中文都是亂碼的,如下:
1??10.2?????
2??45??????
3??78?????
原因:
因?yàn)閠xt文本文件中的中文都不是ascii編碼,所以在讀取出來的時(shí)候需要讀取出來的字符串經(jīng)過解碼才能正常顯示。
解決方案:
只需要在讀取的文件后面進(jìn)行解碼就好了。代碼如下:
f=open("raindata.txt","r")f.readline()#第一行是列,可以將文件移到第二行開始處for line in f: print line.decode("gb2312")
結(jié)果如下:
1,10.2,南京
2,45,北京
3,78,上海
將數(shù)據(jù)正確讀取出來之后就需要把每一行的數(shù)據(jù)存儲到對象中。代碼如下:
f=open("raindata.txt","r")f.readline()#第一行是列,可以將文件移到第二行開始處for line in f: lines=line.decode("gb2312").split(",") obj=Rain(lines[0],lines[1],lines[2]) data.append(obj)
結(jié)果出現(xiàn)了split(",”)這個(gè)方法錯(cuò)誤,提示說這個(gè)方法里面的參數(shù)不是中文編碼。如下:
lines=line.decode("gb2312").split(",")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)
原因:
在網(wǎng)上看了這種錯(cuò)誤的解決方案,說是因?yàn)槲覀兊慕鉀Q方案一種把py的源代碼改為了utf-8的編碼,所以可以解決該文件中所有的中文問題,但是調(diào)用的方法如何使其他模塊中的方法,而方法還出現(xiàn)中文的話,就會提示錯(cuò)誤。
解決方案:
既然知道了原因,那么解決的辦法是,把整個(gè)環(huán)境的編碼默認(rèn)編碼方式都改成utf-8就好了。更改的代碼如下:
import sysdefault_encoding="utf-8"if(default_encoding!=sys.getdefaultencoding()): reload(sys) sys.setdefaultencoding(default_encoding)data =[]f=open("raindata.txt","r")f.readline()#第一行是列,可以將文件移到第二行開始處for line in f: lines=line.decode("gb2312").split(",") obj=Rain(lines[0],lines[1],lines[2]) data.append(obj)
f.close()print len(data)
這樣就解決了。
當(dāng)把文本文件的編碼方式換成了utf-8之后,上面的代碼就出錯(cuò)了,錯(cuò)誤如下:
Traceback (most recent call last):
File "D:/program/java/PythonOne/src/Test/FileHandle.py", line 24, in <module>
lines=line.decode("gb2312").split(",")
UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 3-4: illegal multibyte sequence
原因:
這是因?yàn)楸緛砦募木幋a是utf-8,所以用gb2312的編碼方式去解碼,無疑,那肯定是錯(cuò)誤。然而前面已經(jīng)設(shè)置了本系統(tǒng)默認(rèn)的編碼方式就是utf-8,所以只需要將讀出來的文本去掉gb2312的編碼方式就好了。代碼如下:
import sysdefault_encoding="utf-8"if(default_encoding!=sys.getdefaultencoding()): reload(sys) sys.setdefaultencoding(default_encoding)data =[]f=open("raindata.txt","r")f.readline()#第一行是列,可以將文件移到第二行開始處for line in f: lines=line.split(",") obj=Rain(lines[0],lines[1],lines[2]) data.append(obj)f.close()
這就解決了文本文件為utf-8的編碼方式了。
完成了讀出文本數(shù)據(jù)的工作之后,接下就是將讀入的數(shù)據(jù)寫入文本文件的了。代碼如下:
代碼如下:
f1=open('result.txt','w')for vs in data: f1.write(vs.id+","+vs.acc+","+vs.site) f1.write("/n")
這段寫入數(shù)據(jù)的代碼的分兩種情況。
1、解釋器的默認(rèn)編碼是utf-8的,而文本文件的編碼也是utf-8的,直接寫入,寫入到txt的結(jié)果不會亂碼。
2、而文本文件的編碼也是ascii的,寫入的時(shí)候需要編碼之后再寫入,更改的代碼如下:
f1=open('result.txt','w')for vs in data: f1.write((vs.id+","+vs.acc+","+vs.site).encode("gb2312")) f1.write("/n")fl.close()
到此為止,利用python進(jìn)行讀寫文件的已經(jīng)能夠成功的運(yùn)行的。然而,還補(bǔ)充一點(diǎn),這是在打印列表中的中文時(shí)所照成的問題,并不是亂碼的問題。
我們在打印含有中文的列表的時(shí)候中文得不到有效的輸出,而是以utf-8的編碼輸出。代碼如下:
strs=['你好','hello']print strs
產(chǎn)生的結(jié)果如下:
['/xe4/xbd/xa0/xe5/xa5/xbd', 'hello']
解決方案:
把該列表一項(xiàng)一項(xiàng)的輸出就沒有問題。代碼如下:
strs=['你好','hello']print strs[0],sts[1]
結(jié)果為:
你好 hello
我編寫python的腳本的編輯器為eclipse,在eclipse中的控制臺中的輸出結(jié)果(中文)是正確編碼的,但是在cmd命令窗口中執(zhí)行py腳本顯示的確實(shí)亂碼。打印代碼如下:
print '等待連接'
然后我在cmd窗口中執(zhí)行腳本的時(shí)輸出的情況如下圖:

出現(xiàn)了亂碼。
解決方案:
要讓這個(gè)字符串以utf-8的方式去實(shí)現(xiàn),更改的代碼如下圖:
print u'等待連接'
這下不管是在eclipse的控制臺中輸出的,還是cmd命令窗口中輸出都是正常顯示。
嘗試過這么多錯(cuò)誤之后終于正確的將文本的數(shù)據(jù)讀取,也成功的數(shù)據(jù)寫入到文本文件中??偨Y(jié)一下就那么幾點(diǎn)。
- 源碼中的編碼方式
- 環(huán)境中的默認(rèn)編碼方式
- 結(jié)果文件中的編碼方式
畢竟是初學(xué)python,對于上面的解決方案的解釋的原理可能是錯(cuò)誤的,希望各位大牛在看到錯(cuò)誤的之后能及時(shí)指出來,在此感激不盡。
新聞熱點(diǎn)
疑難解答
圖片精選