實(shí)例講述實(shí)現(xiàn)轉(zhuǎn)中文及轉(zhuǎn)換默認(rèn)編碼的方法(二)
2021-07-21
本文介紹了實(shí)現(xiàn)轉(zhuǎn)中文的方法和默認(rèn)編碼。分享給大家,供大家參考,如下:
一、 爬取網(wǎng)頁(yè)信息的時(shí)候,經(jīng)常需要把“\\\\\\\”之類的東西轉(zhuǎn)成中文,其實(shí)就是中文編碼??梢允褂靡韵路椒ㄟM(jìn)行轉(zhuǎn)換:
1、
>>> s = u'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8' >>> print s 人生苦短,py是岸
2、
>>> s = r'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8' >>> s = s.decode('unicode_escape') >>> print s 人生苦短,py是岸
二、另外,":'' can't in 0-5: not in (128)"的字符編碼問(wèn)題經(jīng)常遇到編碼錯(cuò)誤。
通常可以使用以下方法:
import sys reload(sys) sys.setdefaultencoding('utf-8')
這個(gè)方法就是把默認(rèn)編碼改成utf-8。但是這種方法不是一次性修復(fù)的,可能會(huì)使一些代碼表現(xiàn)得很奇怪。
關(guān)于 sys.('utf-8') 的補(bǔ)充:
sys.('utf-8')導(dǎo)致的兩個(gè)大問(wèn)題
簡(jiǎn)單來(lái)說(shuō),這樣做會(huì)使一些代碼行為變得怪異,而且這種怪異性并不容易修復(fù),因?yàn)榇嬖谝粋€(gè)不可見的錯(cuò)誤。下面我們舉兩個(gè)例子。
1.編碼錯(cuò)誤
import chardet def print_string(string): try: print(u"%s" % string) except UnicodeError: print u"%s" % unicode(byte_string, encoding=chardet.detect(string)['encoding']) print_string(u"??".encode("latin-1")) import sys reload(sys) sys.setdefaultencoding('utf-8') print(key_in_dict('??'))
輸出:
$~ ?? $~ t
以上代碼中,默認(rèn)編碼無(wú)法解碼。 ?? -1 編碼十六進(jìn)制表示 c3 be,這顯然超過(guò)了 128 個(gè)字符的代碼集。引發(fā)異常并進(jìn)入異常處理。異常處理將基于代碼檢測(cè)和最可能解碼的代碼,輸出將更加可靠。
一旦我們?cè)O(shè)置為utf-8,因?yàn)閡tf-8的字符范圍被-1完全覆蓋了,所以我們就直接使用utf-8進(jìn)行解碼了。 c3 be 是 utf-8 中的 t。所以我們打印出完全不同的字符。
你可能會(huì)說(shuō)我們不寫這樣的代碼。如果我們寫了它們,我們會(huì)進(jìn)行更正。但是如果是這樣寫的第三方庫(kù)呢?項(xiàng)目依賴的第三方庫(kù)就是這么有問(wèn)題。如果不依賴第三方庫(kù),那么下面這個(gè)bug就逃不掉了。
2.行為異常
假設(shè)我們想找出一個(gè)鍵是否存在。一般來(lái)說(shuō),可行的方法有兩種。
#-*- coding: utf-8 -*- d = {1:2, '1':'2', '你好': 'hello'} def key_in_dict(key) if key in d: return True return False def key_found_in_dict(key): for _key in d: if _key == key: return True return False
我們來(lái)對(duì)比一下改變系統(tǒng)默認(rèn)編碼前后這兩個(gè)函數(shù)的輸出。
#-*- coding: utf-8 -*- print(key_in_dict('你好')) print(key_found_dict('你好')) print(key_in_dict(u'你好')) print(key_found_in_dict(u'你好')) print('------utf-8------') import sys reload(sys) sys.setdefaultencoding('utf-8') print(key_in_dict('你好')) print(key_found_dict('你好')) print(key_in_dict(u'你好')) print(key_found_in_dict(u'你好'))
輸出:
$~ True $~ True $~ False $~ False $~ ------utf-8------ $~ True $~ True $~ False $~ True
可以看到,改變默認(rèn)編碼后,兩個(gè)函數(shù)的輸出不再一致。
dict 的 in 操作符對(duì)鍵進(jìn)行哈希運(yùn)算,并比較哈希值,以確定它們是否相等。對(duì)于集合中的字符,無(wú)論是字節(jié)字符類型還是類型,哈希值都是一樣的。例如{'1':1}中的u'1'會(huì)返回True,超出代碼集的字符,如上例中的“”,byte字符類型的hash和type的hash是不同的.
== 運(yùn)算符進(jìn)行轉(zhuǎn)換,將字節(jié)字符(byte,上面的'')轉(zhuǎn)換為(u'')類型,然后比較轉(zhuǎn)換后的結(jié)果。在系統(tǒng)默認(rèn)編碼中,"" to的轉(zhuǎn)換會(huì)產(chǎn)生:: to both to-them as,因?yàn)槌龃a集的代碼集無(wú)法轉(zhuǎn)換,系統(tǒng)會(huì)默認(rèn)不相等。當(dāng)系統(tǒng)代碼被我們手動(dòng)改成utf-8后,這個(gè)禁忌就被解除了,“你好”就可以成功轉(zhuǎn)換了。最終結(jié)果是in和==的行為不再一??致。
問(wèn)題的根源:在
為了讓它的語(yǔ)法看起來(lái)簡(jiǎn)潔易用,做了很多事情。一個(gè)例子是字節(jié)和文本之間的混淆。
中,共有三種類型,(text),str(字節(jié),二進(jìn)制數(shù)據(jù)),它們是前兩種的父類型。
其實(shí),在語(yǔ)言設(shè)計(jì)領(lǐng)域,一個(gè)字節(jié)串(of)是否應(yīng)該被當(dāng)作一個(gè)字符串()一直存在爭(zhēng)議。眾所周知的Java和C#投了反對(duì)票,卻站在了支持者的陣營(yíng)。其實(shí)在很多情況下,我們對(duì)文本進(jìn)行的正則匹配、字符替換等操作,對(duì)于字節(jié)來(lái)說(shuō)都是不必要的。并且認(rèn)為字節(jié)是字符,所以它們的操作集是一樣的。
此外,它會(huì)在必要時(shí)嘗試進(jìn)行字節(jié)的自動(dòng)類型轉(zhuǎn)換,例如在上面的 == 或連接字節(jié)和文本時(shí)。沒有(),兩種不同類型之間的轉(zhuǎn)換是不可能的,所以需要一個(gè)默認(rèn)的編碼。在它誕生的年代,它是最受歡迎的(可以這么說(shuō)),所以我選擇了它。但是,眾所周知,在需要轉(zhuǎn)換的場(chǎng)景(128個(gè)字符吃飽)是沒用的。
經(jīng)過(guò)這么多年的抱怨php unicode編碼轉(zhuǎn)漢字,3終于學(xué)會(huì)了怎么做人。默認(rèn)編碼為,表示所有需要轉(zhuǎn)換的情況都可以正確轉(zhuǎn)換成功。
最佳做法
說(shuō)了這么多,如果你不遷移到 3,你能做什么?
有幾點(diǎn)建議:
所有文本都應(yīng)該是 type,而不是 str。如果您正在操作文本并且類型為 str,那么您正在創(chuàng)建一個(gè)錯(cuò)誤。
當(dāng)你需要轉(zhuǎn)換時(shí),顯式轉(zhuǎn)換。要將字節(jié)解碼為文本,請(qǐng)使用 var.(),將文本編碼為字節(jié),請(qǐng)使用 var.()。
從外部讀取數(shù)據(jù)時(shí),默認(rèn)為php unicode編碼轉(zhuǎn)漢字,然后變成需要的文本;同理,當(dāng)文本需要向外發(fā)送時(shí),就變成字節(jié)然后發(fā)送。
PS:這里有一些與編碼轉(zhuǎn)換操作相關(guān)的工具供大家參考:
在線/中文轉(zhuǎn)換工具:
/在線代碼轉(zhuǎn)換工具:
在線漢字/代碼/代碼轉(zhuǎn)換工具:
更多對(duì)相關(guān)內(nèi)容感興趣的讀者可以查看本站專題:《編碼操作技巧總結(jié)》、《圖片操作技巧總結(jié)》、《數(shù)據(jù)結(jié)構(gòu)與算法教程》、《編程技巧總結(jié)》、 《函數(shù)使用技巧》《總結(jié)》《字符串操作技巧總結(jié)》《入門與高級(jí)經(jīng)典教程》《文件與目錄操作技巧總結(jié)》
希望這篇文章對(duì)大家的程序設(shè)計(jì)有所幫助。