Python 2.7 學習筆記 中文處理


首先我們在編寫python代碼文件時,文件本身會采用一種編碼格式,如 utf-8 或 gbk

這時我們需要在python文件的開頭設置文件的編碼格式,以告訴編譯器。

如果文件的編碼格式是 utf-8, 則在文件的第一行需要添加如下語句

#coding=utf-8

如果文件的編碼格式是 gbk, 則在文件的第一行需要添加如下語句

#coding=gbk

如果設置為utf-8的格式,在linux執行,中文處理,包括顯示沒任何問題。

但是如果設置為utf-8的格式,在window下,在命令行下執行時,發現利用 print打印中文會出現亂碼。

原因是因為,雖然文件聲明為utf-8,且用utf-8的編碼保存的源文件。但是windows的本地默認編碼是cp936,也就是gbk編碼,所以在控制台直接打印utf-8的字符串就顯示亂碼了。 注意,實際上只是顯示有問題,入庫等處理並沒問題。

這有兩種解決方案。

一、方案一:

將文件的編碼格式改為gbk,並在文件的第一行改為#coding=gbk,這時處理中文就沒問題。

但這個方案帶來的問題,如果該文件放到Linux下可能會顯示出問題。因為一般linux機器下沒有gbk的字符集。

 

二、方案二

文件還是采用utf-8的編碼,文件頭的第一行依然是#coding=utf-8

這時在print 中文時需要進行下編碼,代碼如:

print "中文".decode('utf-8').encode(sys.getfilesystemencoding())

注意:因為用到了sys模塊,需要在語句執行添加 import sys

這樣帶來的問題,print語句比較臃腫,可以考慮自己封裝下.

 

三、關於 decode 方法和 encode 方法

字符串在Python內部的表示是unicode編碼。在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字符串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。 

decode的作用是將其他編碼的字符串轉換成unicode編碼, 其參數就是字符串的當前編碼格式。如str.decode('utf-8'),表示將utf-8編碼的字符串轉換成unicode編碼。 

encode的作用是將unicode編碼轉換成其他編碼的字符串, 其參數就是希望轉換后的編碼格式。如str.encode('utf-8'),表示將unicode編碼的字符串轉換成utf-8編碼。

不能直接將一種編碼(非unicode)的字符串利用encode方法直接轉換為其它的編碼格式。

 注意:unicode 和 其它的編碼字符串在python 是完全不同的兩種數據類型,unicode的字符串時unicode類型的, 其它的是str類型。

在python中,對於字面字符串我們可以在字面字符串前加u把該字符串聲明為unicode類型的。

下面我們來看一個例子了解unicode和str類型的區別

>>> s='測試'
>>> us=u'測試unicode'
>>> print isinstance(s,str)
True
>>> print isinstance(s,unicode)
False
>>> print isinstance(us,str)
False
>>> print isinstance(us,unicode)
True
>>> print isinstance(us.encode('utf-8'),unicode)
False
>>> print isinstance(us.encode('utf-8'),str)
True
>>> print isinstance(s.decode('gbk'),unicode) #是在windows下執行,默認的s是gbk編碼
True


利用第三方包  chardet的detect方法可以檢查一個字符串具體的編碼格式,如:

>>> import chardet
>>> chardet.detect('中文')
{'confidence': 0.682639754276994, 'encoding': 'KOI8-R'} #在window下執行的
>>> chardet.detect('str123')
{'confidence': 1.0, 'encoding': 'ascii'}
>>> chardet.detect(u'中文')   #無法對unicode類型進行檢查
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda2\lib\site-packages\chardet\__init__.py", line 25, in de
    raise ValueError('Expected a bytes object, not a unicode object')
ValueError: Expected a bytes object, not a unicode object
>>> chardet.detect(u'中文'.encode('utf8'))  #參數為utf-8的
{'confidence': 0.7525, 'encoding': 'utf-8'}

 

四、與中文相關的常見處理場景

在程序編寫中,一般涉及到中文我們才需要編解碼。 通常有如下幾種場景:

1、將文件中硬編碼的中文字符串利用print輸出,就如上面介紹的例子:

str = "中文"

print  str

str = str.decode('utf-8').encode(sys.getfilesystemencoding())

print str

上面的代碼假設文件的編碼格式為utf-8,當在windows命令行下執行時,第一個print語句輸出的是亂碼。

我們先調用decode方法將其轉為 unicode編碼,然后在調用encode方法轉為系統編碼的格式。

 

2、當我們用raw_input從控制台獲取字符串時

這時獲取到的字符串的編碼時系統編碼,不一定是utf-8,這時我們想要轉為utf-8,可以用如下的方法

msg = raw_input(">")
msg = msg.decode(sys.getfilesystemencoding()).encode('utf-8')

上面代碼先將字符串解碼成unicode編碼,再編碼成utf-8

 

3、列表或字典中的中文處理

data = {"a":"hello","b":"中國"}  #假設是utf-8的格式

這時我們用print直接輸出data, 或用str函數將data轉為字符串。其中的中文是變成unicode的字符,如:

>>> data = {"a":"hello","b":"中國"}
>>> print data
{'a': 'hello', 'b': '\xd6\xd0\xb9\xfa'}

單獨輸出中文字段沒問題,如

>>> print data['b']
中國

如果希望能正常的將整個字典輸出,可以利用json包的dump方法,如:

>>> data = {"a":"hello","b":"中國"}
>>> s = json.dumps(data,ensure_ascii=False);
>>> print s
{"a": "hello", "b": "中國"}

>>> print isinstance(s,str)
True

 

4、當我們利用os的相關方法時,傳入的字符串編碼需要與系統一致,如:

filename = "D:/測試.txt";  # 假設是utf-8的格式

filename = filename.decode("utf-8").encode(sys.getfilesystemencoding()); #轉為當前系統字符集

re = os.path.exists(filename)  # 檢查文件是否存在,必須要上面的先轉換為當前系統字符集才會正確

filename = filename.decode(sys.getfilesystemencoding()).encode("utf-8"); #重新轉為utf-8

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM