Python中文全詳解

來源:互聯網
上載者:User

1.        在python中使用中文

在python中有兩種預設的字串:str和unicode。在python中一定要注意區分“unicode字串”和“unicode對象”的區別。後面所有的“unicode字串”指的都是python裡的“unicode對象”。
事實上在python中並沒有“unicode字串”這樣的東西,只有“unicode”對象。一個傳統意義上的unicode字串完全可以用str對象表示。只是這時候它僅僅是一個位元組流,除非解碼為unicode對象,沒有任何實際的意義。
我們用“哈哈”在多個平台上測試,其中“哈”對應的不同編碼是:
1.              unicode (utf8-16),      c854;
2.              utf-8,                    e59388;
3.              gbk,               b9fe。
1.1     windows控制台
下面是在windows控制台的運行結果:
可以看出在控制台,中文字元的編碼是gbk而不是utf-16。將字串s(gbk編碼)使用decode進行解碼後,可以得到同等的unicode對象。
注意:可以在控制台列印ss並不代表它可以直接被序列化,比如:
向檔案直接輸出ss會拋出同樣的異常。在處理unicode中文字串的時候,必須首先對它調用encode函數,轉換成其它編碼輸出。這一點對各個環境都一樣。
總結:在python中,“str”對象就是一個位元組數組,至於裡面的內容是不是一個合法的字串,以及這個字串採用什麼編碼(gbk, utf-8, unicode)都不重要。這些內容需要使用者自己記錄和判斷。這些的限制也同樣適用於“unicode”對象。要記住“unicode”對象中的內容可絕對不一定就是合法的unicode字串,我們很快就會看到這種情況。
總結:在windows的控制台上,支援gbk編碼的str對象和unicode編碼的unicode對象。
1.2     windows idle(在shell上運行)
在windows下的idle中,運行效果和windows控制台不完全一致:
可以看出,對於不使用“u”作標識的字串,idle把其中的中文字元進行gbk編碼。但是對於使用“u”的unicode字串,idle居然一樣是用了gbk編碼,不同的是,這時候每一個字元都是unicode(對象)字元!!此時len(ss) = 4。
這樣產生了一個神奇的問題,現在的ss無法在idle中正常顯示。而且我也沒有辦法把ss轉換成正常的編碼!比如採用下面的方法:
這有可能是因為idle本地化做得不夠好,對中文的支援有問題。建議在idle的shell中,不要使用u“中文”這種方式,因為這樣得到的並不是你想要的東西。
這同時說明idle的shell支援兩種格式的中文字串:gbk編碼的“str”對象,和unicode編碼的unicode對象。
1.3     在idle上運行代碼
在idle的shell上運行檔案,得到的又是不同的結果。檔案的內容是:
直接啟動並執行結果是:
 
毫無瑕疵,相當令人滿意。我沒有試過其它編碼的檔案是否能正常運行,但想來應該是不錯的。
同樣的代碼在windows的控制台試演過,也沒有任何問題。
1.4     windows eclips教程e
在eclipse中處理中文更加困難,因為在eclipse中,編寫代碼和運行代碼屬於不同的視窗,而且他們可以有不同的預設編碼。對於如下代碼:
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
s =  " 哈哈 "
ss = u ' 哈哈 '
 
print repr(s)
print repr(ss)
 
print s.decode( 'utf-8').encode( 'gbk')
print ss.encode( 'gbk')
 
print s.decode( 'utf-8')
print ss
 
前四個print運行正常,最後兩個print都會拋出異常:
'xe5x93x88xe5x93x88'
u'u54c8u54c8'
哈哈
哈哈
traceback (most recent call last):
 file "e:workspaceeclipsetestpythontesttest_encoding_2.py", line 13, in <module>
    print s.decode('utf-8')
unicodeencodeerror: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
也就是說,gbk編碼的str對象可以正常列印,但是不能列印unicode編碼的unicode對象。在源檔案上點擊“run as”“run”,然後在彈出對話方塊中選擇“common”:
可以看出eclipse控制台的預設編碼方式是gbk;所以不支援unicode也在情理之中。如果把檔案中的coding修改成gbk,則可以直接列印gbk編碼的str對象,比如s。
如果把源檔案的編碼設定成“utf-8”,把控制台的編碼也設定成“utf-8”,按道理說列印的時候應該沒有問題。但是實驗表明,在列印utf-8編碼的str對象時,中文的最後一個字元會顯示成亂碼,無法正常閱讀。不過我已經很滿足了,至少人家沒有拋異常不是:)
btw: 使用的eclipse版本是3.2.1。
1.5     從檔案讀取中文
在window下面用記事本編輯檔案的時候,如果儲存為unicode或utf-8,分別會在檔案的開頭加上兩個位元組“xffxfe”和三個位元組“xefxbbxbf”。在讀取的時候就可能會遇到問題,但是不同的環境對這幾個多於字元的處理也不一樣。
以windows下的控制台為例,用記事本儲存三個不同版本的“哈哈”。
 
開啟utf-8格式的檔案並讀取utf-8字串後,解碼變成unicode對象。但是會把附加的三個字元同樣進行轉換,變成一個unicode字元,字元的資料值為“xffxfe”。這個字元不能被列印。編碼的時候需要跳過這個字元。
開啟unicode格式的檔案後,得到的字串正確。這時候適用utf-16解碼,能得到正確的unicdoe對象,可以直接使用。多餘的那個填充字元在進行轉換時會被過濾掉。
 
開啟ansi格式的檔案後,沒有填充字元,可以直接使用。
結論:讀寫使用python產生的檔案沒有任何問題,但是在處理由notepad產生的文字檔時,如果該檔案可能是非ansi編碼,需要考慮如何處理填充字元。
1.6     在資料庫教程中使用中文
剛剛接觸python,我用的資料庫是mysql教程。在執行插入、尋找等操作時,如果運行環境使用的字元編碼和mysql不一致,就可能導致運行時的錯誤。當然,和上面看到的情況一樣,運行環境並不是關鍵因素,關鍵是 查詢語句的編碼方式。如果在每次執行查詢操作時都把查詢字串做一次編碼轉換,轉變成mysql的預設字元編碼,一樣不會遇到問題。但是這樣寫代碼也太痛苦了吧。
使用如下代碼串連資料庫:
self.conn = mysqldb.connect(use_unicode = 1, charset= 'utf8', **server)
我不能理解的是既然資料庫用的預設編碼是utf-8,我串連的時候也用的是utf-8,為什麼查詢得到的常值內容卻是unicode編碼(unicode對象)?這是mysqldb庫的設定嗎?
1.7     在xml中使用中文
使用xml.dom.minidom和mysqldb類似,對產生的dom對象調用toxml方法得到的是unicode對象。如果希望輸出utf-8文本,有兩種方法:
1 .使用系統函數
在輸出xml文檔的時候進行編碼,這是我覺得最好的方法。
xmldoc.toxml(encoding=’utf-8’)
xmldoc.writexml(outfile, encoding = ‘utf-8’)
2 .自己編碼產生
在使用toxml之後可以調用encode方法對文檔進行編碼。但這種方法無法得到合適的xml declaration(xml文檔第一行中的encoding部分)。
不要嘗試通過xmldoc.createprocessinginstruction來建立一個processing instraction:
<?xml version=’1.0’ encoding=’utf-8’?>
xml declaration雖然看起來像是,但是事實上並不是一個processing instraction。可以通下面的方法得到一個滿意的xml檔案:
print >> outfile, “<?xml version=’1.0’ encoding=’utf-8’?>”
print >> outfile, xmldoc.toxml().encode(‘utf-8’)[22:]
其中第二行需要過濾掉在調用xmldoc.toxml時產生的“<?xml version=’1.0’ ?>”,它的長度是22。
 
相面是兩種方法的用法比較:
 
另外,在idle的shell中,不要用 u’中文’ 對屬性進行賦值。上面討論過,這樣得到的unicode字串不正確

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.