官术网_书友最值得收藏!

2.5.3 Python的編碼問題

下面來了解一下在Python中常見的編碼方式。

·GB2312:中國規定的漢字編碼,也可以說是簡體中文的字符集編碼。

·GBK:GB2312的擴展,除了兼容GB2312外,它還能顯示繁體中文,還有日文的假名。

·CP936:CP936其實就是GBK,IBM在發明Code Page時將GBK放在了第936頁,所以也稱為CP936。

·Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。UTF-8、UTF-16、UTF-32都是將數字轉換到程序數據的編碼方案。UTF-8(8-bit Unicode Transformation Format)是最流行的一種對Unicode進行傳播和存儲的編碼方式。它用不同的Byte來表示每一個代碼點。每個ASCII字符只需要用一個Byte,與ASCII的編碼是一樣的。所以說ASCII是UTF-8的一個子集。

在開發Python程序的過程中,會涉及三個方面的編碼:

·Python程序文件的編碼。

·Python程序運行時環境的編碼。

·Python程序讀取外部文件、網頁的編碼。

下面用程序來看一下不同的編程情況。

1)Python程序文件的編輯,這里還是沿用前面的環境,先用PyCharm寫一段測試代碼,內容如下:


print 'hello,余江洪!'

然后執行,報錯如下:


File "test1.py", line 1
SyntaxError: Non-ASCII character '\xe4' in file test1.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

這是因為PyCharm編輯器默認的編碼是ASCII,它是無法識別中文的,所以會彈出這樣的提示。這也是我們在大多數情況下寫Python程序時習慣在第一行加上以下語句的原因:


#-*- encoding:utf-8 -*-

聲明文件編碼即可解決問題。

2)Python程序運行時系統環境或IDE的編輯。假設這里有IPython,輸入如下命令:


In [1]: import sys
In [2]: sys.getdefaultencoding()

顯示結果如下:


Out[2]: 'ascii'

那么我們應該如何修改成UTF-8編碼呢?需要在程序前面加上如下三行:


import sys
reload(sys)
sys.setdefaultencoding('utf-8')

對應C/C++的char和wchar_t,Python中也有兩種字符串類型,即str與unicode。那么,我們應該如何來區分它們呢?

其實這和密碼領域類似,從明文到密碼是加密,從密碼到明文是解密。在Python語言的設計中,編碼為Unicode→str,解碼則為str→Unicode。編碼和解碼也會涉及編碼/解碼方案(對應加密/解密算法),Unicode相當于明文,其他編碼則相當于密碼。在Python中,編碼函數是encode(),解碼函數是decode()。所以,從Unicode轉str是encode(),而反過來叫decode()。

下面寫一個小程序來驗證:


#-*- encoding:utf-8 -*-
import sys
import string
#設置sys.getdefaultencoding()的值為'utf-8'  
reload(sys)                      #reload才能調用setdefaultencoding方法  
sys.setdefaultencoding('utf-8')  #設置'utf-8'   
  
#這個是str的字符串  
s = '新年快樂'  
#這個是Unicode的字符串  
u = u'新年快樂'  
  
print isinstance(s, str)      #True  
print isinstance(u, unicode)  #True
#從str轉換成Unicode  
print s.decode('utf-8') 
#從Unicode轉換成str  
print u.encode('utf-8')

輸出結果如下:


True
True
新年快樂
新年快樂

在工作中常會存在中文輸入報錯的問題,這里可以寫一個函數來驗證輸入的Unicode是否是中文,程序內容如下:


#!/usr/bin/env python
-*- coding:utf-8-*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
 
# 判斷一個Unicode是否是中文
def is_chinese(uchar):         
    if u'\u4e00' <= uchar<=u'\u9fff':
        print 'yes'
        return True
    else:
        print 'no'
        return False

is_chinese('余洪春')

3)對于外部文件或網頁,我們可以利用chardet模塊來正確識別它們到底采取的是哪種編碼。chardet是一個非常優秀的編碼識別模塊。另外,它是Python的第三方庫,需要下載和安裝,這里直接用pip命令來安裝:


pip install chardet

以筆者的技術博客來舉例說明如何利用chardet得知網頁編碼方式,代碼如下:


#!/usr/bin/env python
import chardet
import urllib

myweb = urllib.urlopen('http://yuhongchun.blog.51cto.com').read()
char = chardet.detect(myweb)
print char

代碼運行結果如下:


{'confidence': 0.99, 'language': '', 'encoding': 'utf-8'}

結果表示有99%的概率認為這段代碼是UTF-8編碼方式。

主站蜘蛛池模板: 连平县| 修水县| 河津市| 台北市| 洞头县| 汝南县| 达尔| 安西县| 巴彦县| 万源市| 鸡泽县| 澜沧| 即墨市| 四平市| 甘南县| 皮山县| 施甸县| 延安市| 隆尧县| 辛集市| 安仁县| 泌阳县| 喀喇沁旗| 浙江省| 桐庐县| 西和县| 长宁县| 山西省| 工布江达县| 伽师县| 民乐县| 高邮市| 长岛县| 江源县| 若羌县| 汤阴县| 青铜峡市| 永泰县| 会泽县| 塔河县| 长顺县|