python转载[编码问题]
?
轉(zhuǎn)自: http://www.javaeye.com/topic/560229
?
一 預(yù)備知識(shí)
字符集
1, 常用字符集分類
ASCII及其擴(kuò)展字符集
作用:表語英語及西歐語言。
位數(shù):ASCII是用7位表示的,能表示128個(gè)字符;其擴(kuò)展使用8位表示,表示256個(gè)字符。
范圍:ASCII從00到7F,擴(kuò)展從00到FF。
ISO-8859-1字符集
作用:擴(kuò)展ASCII,表示西歐、希臘語等。
位數(shù):8位,
范圍:從00到FF,兼容ASCII字符集。
GB2312字符集
作用:國家簡體中文字符集,兼容ASCII。
位數(shù):使用2個(gè)字節(jié)表示,能表示7445個(gè)符號(hào),包括6763個(gè)漢字,幾乎覆蓋所有高頻率漢字。
范圍:高字節(jié)從A1到F7, 低字節(jié)從A1到FE。將高字節(jié)和低字節(jié)分別加上0XA0即可得到編碼。
BIG5字符集
作用:統(tǒng)一繁體字編碼。
位數(shù):使用2個(gè)字節(jié)表示,表示13053個(gè)漢字。
范圍:高字節(jié)從A1到F9,低字節(jié)從40到7E,A1到FE。
GBK字符集
作用:它是GB2312的擴(kuò)展,加入對(duì)繁體字的支持,兼容GB2312。
位數(shù):使用2個(gè)字節(jié)表示,可表示21886個(gè)字符。
范圍:高字節(jié)從81到FE,低字節(jié)從40到FE。
GB18030字符集
作用:它解決了中文、日文、朝鮮語等的編碼,兼容GBK。
位數(shù):它采用變字節(jié)表示(1 ASCII,2,4字節(jié))。可表示27484個(gè)文字。
范圍:1字節(jié)從00到7F; 2字節(jié)高字節(jié)從81到FE,低字節(jié)從40到7E和80到FE;4字節(jié)第一三字節(jié)從81到FE,第二四字節(jié)從30到39。
UCS字符集
作用:國際標(biāo)準(zhǔn) ISO 10646 定義了通用字符集 (Universal Character Set)。它是與UNICODE同類的組織,UCS-2和UNICODE兼容。
位數(shù):它有UCS-2和UCS-4兩種格式,分別是2字節(jié)和4字節(jié)。
范圍:目前,UCS-4只是在UCS-2前面加了0×0000。
UNICODE字符集
作用:為世界650種語言進(jìn)行統(tǒng)一編碼,兼容ISO-8859-1。
位數(shù):UNICODE字符集有多個(gè)編碼方式,分別是UTF-8,UTF-16和UTF-32。
2?,按所表示的文字分類
語言?????????????????????????????????字符集?????????????????????????????????????正式名稱
英語、西歐語?????????????????????ASCII,ISO-8859-1????????????????MBCS 多字節(jié)
簡體中文?????????????????????????????GB2312?????????????????????????????????? ?MBCS 多字節(jié)
繁體中文?????????????????????????????BIG5?????????????????????????????????????????MBCS 多字節(jié)
簡繁中文?????????????????????????????GBK?????????????????????????????????????????MBCS 多字節(jié)
中文、日文及朝鮮語?????????GB18030????????????????????????????????? MBCS 多字節(jié)
各國語言?????????????????????????????UNICODE,UCS????????????????????DBCS 寬字節(jié)
編碼
UTF-8:采用變長字節(jié) (1 ASCII, 2 希臘字母, 3 漢字, 4 平面符號(hào)) 表示,網(wǎng)絡(luò)傳輸, 即使錯(cuò)了一個(gè)字節(jié),不影響其他字節(jié),而雙字節(jié)只要一個(gè)錯(cuò)了,其他也錯(cuò)了,具體如下:
如果只有一個(gè)字節(jié)則其最高二進(jìn)制位為0;如果是多字節(jié),其第一個(gè)字節(jié)從最高位開始,連續(xù)的二進(jìn)制位值為1的個(gè)數(shù)決定了其編碼的字節(jié)數(shù),其余各字節(jié)均以10開頭。UTF-8最多可用到6個(gè)字節(jié)。
UTF-16:采用2字節(jié),Unicode中不同部分的字符都同樣基于現(xiàn)有的標(biāo)準(zhǔn)。這是為了便于轉(zhuǎn)換。從 0×0000到0×007F是ASCII字符,從0×0080到0×00FF是ISO-8859-1對(duì)ASCII的擴(kuò)展。希臘字母表使用從0×0370到 0×03FF 的代碼,斯拉夫語使用從0×0400到0×04FF的代碼,美國使用從0×0530到0×058F的代碼,希伯來語使用從0×0590到0×05FF的代 碼。中國、日本和韓國的象形文字(總稱為CJK)占用了從0×3000到0×9FFF的代碼;由于0×00在c語言及操作系統(tǒng)文件名等中有特殊意義,故很 多情況下需要UTF-8編碼保存文本,去掉這個(gè)0×00。舉例如下:
UTF-16: 0×0080? = 0000 0000 1000 0000
UTF-8:?? 0xC280 = 1100 0010 1000 0000
UTF-32:采用4字節(jié)。
優(yōu)缺點(diǎn)
UTF-8、UTF-16和UTF-32都可以表示有效編碼空間 (U+000000-U+10FFFF) 內(nèi)的所有Unicode字符。
使用UTF-8編碼時(shí)ASCII字符只占1個(gè)字節(jié),存儲(chǔ)效率比較高,適用于拉丁字符較多的場合以節(jié)省空間。
對(duì)于大多數(shù)非拉丁字符(如中文和日文)來說,UTF-16所需存儲(chǔ)空間最小,每個(gè)字符只占2個(gè)字節(jié)。
Windows NT內(nèi)核是Unicode(UTF-16),采用UTF-16編碼在調(diào)用系統(tǒng)API時(shí)無需轉(zhuǎn)換,處理速度也比較快。
采用UTF-16和UTF-32會(huì)有Big Endian和Little Endian之分,而UTF-8則沒有字節(jié)順序問題,所以UTF-8適合傳輸和通信。
UTF-32采用4字節(jié)編碼,一方面處理速度比較快,但另一方面也浪費(fèi)了大量空間,影響傳輸速度,因而很少使用。
?
二 轉(zhuǎn)載
python與字符編碼:
ASCII 是一種字符集,包括大小寫的英文字母、數(shù)字、控制字符等,它用一個(gè)字節(jié)表示,范圍是 0-127。
Unicode分為UTF-8和UTF-16。UTF-8變長度的,最多 6 個(gè)字節(jié),小于 127 的字符用一個(gè)字節(jié)表示,與 ASCII 字符集的結(jié)果一樣,ASCII 編碼下的英語文本不需要修改就可以當(dāng)作 UTF-8 編碼進(jìn)行處理。
Python 從 2.2 開始支持 Unicode ,函數(shù) decode( char_set )可以實(shí)現(xiàn) 其它編碼到 Unicode 的轉(zhuǎn)換,函數(shù) encode( char_set )實(shí)現(xiàn) Unicode 到其它編碼方式的轉(zhuǎn)換。
比如 ("你好").decode( "GB2312") 將得到 u'\u4f60\u597d',即 "你"和“好"的 Unicode 碼分別是 0x4f60 和 0x597d,再用 (u'\u4f60\u597d').encode("UTF-8") 將得到 '\xe4\xbd\xa0\xe5\xa5\xbd',它是? “你好”的UTF-8編碼結(jié)果。
python中使用 unicode的關(guān)鍵:
unicode是一個(gè)類,函數(shù)unicode(str,"utf8")從utf8編碼(當(dāng)然也可以是別的編碼)的字符串str生成 unicode類的對(duì)象,函數(shù)unc.encode("utf8")將unicode類的對(duì)象unc轉(zhuǎn)換為(編碼為)utf8編碼(當(dāng)然也可以是別的編碼)的字符串。
于是,編寫unicode相關(guān)程序,需要做的事情是:
* 獲取數(shù)據(jù)(字符串)時(shí),用unicode(str, "utf8")生成unicode對(duì)象
* 在程序中僅使用unicode對(duì)象,對(duì)程序中出現(xiàn)的字符串常量都以u(píng)"字符串"的形式書寫
* 輸出時(shí),可將unicode對(duì)象轉(zhuǎn)換為任意編碼輸出,使用str.encode("some_encoding")
>>> unicode("你好", "utf8")
u'\u4f60\u597d'
>>> x = _
>>> type(x)
<type 'unicode'>
>>> type("你好")
<type 'str'>
>>> x.encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> x.encode("gbk")
'\xc4\xe3\xba\xc3'
>>> x.encode("gb2312")
'\xc4\xe3\xba\xc3'
>>> print x
你好
>>> print x.encode("utf8")
你好
>>> print x.encode("gbk")
???
?
python里面基本上要考慮三種編碼格式:
1 源文件編碼
在文件頭部使用coding聲明。告訴python解釋器該代碼文件所使用的字符集。
#/usr/bin/python
#coding: utf8
2 內(nèi)部編碼
代碼文件中的字符串,經(jīng)過decode以后,被轉(zhuǎn)換為統(tǒng)一的unicode格式的內(nèi)部數(shù)據(jù),類似于u'*'。unicode數(shù)據(jù)可以使用encode函數(shù),再自由轉(zhuǎn)換為其他格式的數(shù)據(jù),相當(dāng)于一個(gè)統(tǒng)一的平臺(tái)。
直接輸入unicode數(shù)據(jù)
>>> u'你好'
u'\u4f60\u597d'
將unicode數(shù)據(jù)轉(zhuǎn)換為gb2312格式
>>> u'你好'.encode('gb2312')
'\xc4\xe3\xba\xc3'
將輸入的gb2312格式的數(shù)據(jù)解碼為unicode
>>> '你好'.decode('gb2312')
u'\u4f60\u597d'
輸入數(shù)據(jù)的格式取決于所用shell終端的編碼設(shè)置,本例中為zh_CN
[root@chenzheng python]# echo $LANG
zh_CN
解碼同時(shí)轉(zhuǎn)換為utf8
>>> '你好'.decode('gb2312').encode('utf8')
'\xe4\xbd\xa0\xe5\xa5\xbd'
3 外部輸入的編碼
其實(shí)這個(gè)和在python交互shell中輸入的字符串,所遇到的情況基本一樣。但程序中常常用到從網(wǎng)絡(luò),文件讀取的數(shù)據(jù),故此單獨(dú)列出,需要特別注意其編碼格式是否于系統(tǒng)要求相符。
下面是baidu中文本周金曲榜的鏈接,返回一個(gè)xml文件,編碼格式為gb2312
http://box.zhangmen.baidu.com/x?op=4&listid=1
由于xml.etree.EelementTree.parse()不識(shí)別gb2312編碼,在解析的時(shí)候,需要將其轉(zhuǎn)換utf8格式才可以,可以使用下面的函數(shù)
def read_page(url):
"""讀取gb2312編碼的xml文件,轉(zhuǎn)換為utf8格式"""
import urllib
udata = urllib.urlopen(url).read().decode('gb2312')
u8data = udata.encode('utf8')
return u8data.replace('gb2312', 'utf-8') #簡單替換xml文件第一行的encoding屬性值
另外,可以使用一個(gè)小函數(shù)來判斷數(shù)據(jù)的編碼格式:
def encoding(s):
cl = ['utf8', 'gb2312']
for a in cl:
try:
s.decode(a)
return a
except UnicodeEncodeError:
pass
return 'unknown'?
?
完!
轉(zhuǎn)載于:https://www.cnblogs.com/itech/archive/2011/03/28/1997212.html
總結(jié)
以上是生活随笔為你收集整理的python转载[编码问题]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VI 配置
- 下一篇: Python中纠结处之其一—— 静态方法