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編碼方式。
- 全屋互聯:智能家居系統開發指南
- Containerization with LXC
- Designing Purpose:Built Drones for Ardupilot Pixhawk 2.1
- WindowsServer2012Hyper-V虛擬化部署與管理指南
- 精解Windows8
- Ceph分布式存儲實戰
- NetDevOps入門與實踐
- 分布式高可用架構之道
- Windows 7使用詳解(修訂版)
- Java EE 7 Developer Handbook
- 鴻蒙HarmonyOS應用開發入門
- OpenSolaris系統管理
- Linux服務器配置與管理完全學習手冊
- 庖丁解牛Linux操作系統分析
- Docker實踐(第2版)