python編碼問題

初學Python,遇到很多編碼問題,記下來以免將來又忘了,很多東西不懂,都是屬於不求甚解,亂下結論,但想到拿出來可以有熱心同學指出錯誤所在,便厚起臉皮了……
首先需要了解Python中有兩種字符串(嚴格地說,似乎不能這麼叫)。一種是普通的str對象(每個字符用8bits表示),另一種是unicode字符串,它們可以相互轉換。
首先打開pyshell,輸入一段代碼。

python 代碼

看出來了吧,兩種字符串。
再來

python 代碼

變量a是兩個字符,b是一個unicode字符。
關於這兩種字符串,Python文檔-->LanguageReference-->DataModel-->The standard type hierarchy-->Sequences,有一些Strings,Unicode的描述。
至於

python 代碼

看到了吧,這個奇怪的東西......
後來在WindowsXP、純python命令行下試過,得出的結論不同,z的結果變成了u'/u6211',這裏完全不應該在pyshell下作試驗的,看來還有很多問題尚未理解清楚


再來看看encode,decode
什麼情況用encode,什麼情況又是decode呢,剛開始總是被搞昏。其實各種本地字符集的英文名是Coded Character Set,要轉換爲Coded,肯定是要encode了,同樣,從裏面解出來也應該叫decode……
decode就是把其他編碼轉換爲unicode,等同於unicode函數;encode就是把unicode編碼的字符串轉換爲特定編碼。在pyshell裏繼續:
a是Str類型的,所以再用encode會報錯。用print輸出時會調用默認編碼轉換爲系統編碼?

python 代碼

b是unicode類型,打印時需要先encode(編碼)成系統編碼

python 代碼
 

python裏默認的encode和decode是strict模式,所以會直接拋出Error,而Java裏是默認replace模式,所以在處理servlet時經常會看到一串?????
在decode時傳入第二個參數errors爲'replace'可以和Java相同,但總是沒成功,還不知道爲什麼

MySQLDb連接數據庫的編碼問題
試了很久,無論在connect的時候指定charset='utf8',還是使用set_character_set(),或者執行"SET NAMES UTF8",跟蹤到character_set_name()方法返回的都是latin1...再跟代碼,似乎就跑到mysql-api裏去了,反正最後解決的辦法也很簡單,就是使用如下方式執行,而不要去拼sql語句……

python 代碼

Python的國際化/i18n問題
使用gettext來實現。其實就是一個文本替換的方式,和java裏用ResourceBundle、properties比較類似……
http://wiki.wxpython.org/index.cgi/RecipesI18n有一個recipe,不過代碼很舊了,現在python裏自帶了pygettext.py和msgfmt.py
其實就是把http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx的文章按自己思路組織了一下。
步驟:
1.導入gettext模塊

python 代碼

參數說明:
作用域:用於限定翻譯文件的主名
路徑:翻譯文件所在路徑
unicode:使用unicode

2.把代碼裏需要國際化的文本全部使用_("text")的形式進行替換

3.需要進行國際化處理時,調用

python 代碼

來處理。

現在程序寫好了,需要生成所需資源文件了:
1.調用python安裝目錄的 Tools/i18n/pygettext.py抽取所需翻譯的模板
>>> pygettext.py path/to/yourfile.py
將生成一個名爲messages.pot的文件
2.生成模板文件後,修改這個模板文件,其中的msgid爲鍵值,對應你程序裏寫的文本,如:_("New File"),而msgstr爲翻譯後的值。還有就是注意修改文件頭部分Content-Type的charset爲合適的編碼,比如utf8
3.編寫好模板後,把擴展名修改爲.po,運行Tools/i18n/msgfmt.py,生成二進制的資源文件
>>> msgfmt.py messages.po
將生成一個名爲messages.mo的文件
4.把這個mo文件放在正確的位置.
比如你在程序中是這樣寫的:
gettext.install('i18ntest', './locale', unicode=True)
gettext.translation('i18ntest', './locale', languages=['cn']).install(True)
那麼你的程序目錄下需要存在./local/cn/LC_MESSAGES/i18ntest.mo
這樣程序啓動時就會讀取這個資源文件,替換對應的文本,實現國際化了。
注意:如果使用utf格式保存,po文件不能有BOM頭。cn目錄是所對應的語言,LC_MESSAGES目錄是gettext.py裏要求的,mo文件必須和所定義的域同名,見
gettext.py的mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)

學習資料

All About Python and Unicode http://boodebr.org/main/python/all-about-python-and-unicode
徹底瞭解python的編碼問題 http://blog.csdn.net/iamjianglibo/archive/2007/02/07/1504819.aspx
Python中文問題研究 http://hi.baidu.com/daping_zhang/blog/item/09dda71ea9d7d21f4134173e.html
MySQLdb帶中文參數的問題 http://bbs.chinaunix.net/archiver/?tid-833164.html
wxPython RecipesI18n http://wiki.wxpython.org/index.cgi/RecipesI18n
limodou的blog和ulipad/doc/i18n.htm
http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28947.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28961.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章