python 输出字符串编码_Python print 字符串编码问题
又一次, 被Python的編碼問(wèn)題搞得焦頭爛額. 過(guò)去的記憶中, Python給我的印象之一就是讓人痛不欲生的編碼問(wèn)題, 后來(lái)基本不碰Python很可能與此有關(guān). 這次又用到Python了, 基本上, 整個(gè)過(guò)程還是比較順暢的, Python在某些問(wèn)題上面的確有優(yōu)勢(shì). 但是不可避免的又碰到編碼問(wèn)題.
編碼問(wèn)題是那種你希望永遠(yuǎn)不要碰到, 而一旦碰到就會(huì)很頭疼的一類問(wèn)題. 是一種在解決實(shí)際問(wèn)題過(guò)程中不可避免會(huì)碰到的不愉快的小插曲之一.
事情是這樣, 在Python中調(diào)用win32的api, 枚舉所有活動(dòng)的窗口, 得到窗口的句柄, 窗口標(biāo)題, 和窗口類名, 拿到這些數(shù)據(jù)之后, 用print 輸出到控制臺(tái)中. 開(kāi)始一切都很好, 突然某次在運(yùn)行的時(shí)候出錯(cuò): UnicodeEncodeError, 但是之前都沒(méi)有報(bào)過(guò)錯(cuò), 而且接下來(lái)問(wèn)題時(shí)有時(shí)無(wú).
原因在于, Chrome瀏覽器窗口的標(biāo)題是可以包含特殊字符的, 這里面的文本可能是任何東西, 有些時(shí)候標(biāo)題中的字符都能用gbk表示, 有時(shí)候就會(huì)包含特殊字符.
例如, 打開(kāi)某個(gè)頁(yè)面, 碰巧標(biāo)題是下面的字符串:
how to create a windows service in python ? Python recipes ? ActiveState Code
這里面的字符?就是unicode字符, 在gbk中是不存在的, 在HTML用
?
來(lái)表示.
如果在cmd中運(yùn)行腳本, print到控制臺(tái)中會(huì)拋出UnicodeEncodeError異常. 因?yàn)槟J(rèn)cmd里面的編碼是gbk, print要想輸出則必須先將unicode轉(zhuǎn)換為gbk, 然而gbk里面沒(méi)有某些unicode字符的對(duì)應(yīng)字符, 結(jié)果就拋出異常:
UnicodeEncodeError: 'gbk' codec can't encode character '\xab' in position 42: illegal multibyte sequence
來(lái)分析一下原因, 首先, 從窗口中取得的標(biāo)題字符串是unicode的, 那么print函數(shù)要將其輸出到控制臺(tái), 必須變成控制臺(tái)的編碼, 在windows里, 控制臺(tái)的編碼就是gbk. 在print函數(shù)內(nèi)部必然要用encode將unicode變成gbk, 如果unicode中包含了gbk所不能表示是字符, 則根據(jù)error handling的值決定下一步動(dòng)作, 而Python的默認(rèn)error handling是'strict', 也就是當(dāng)不能encode的時(shí)候拋出異常. 這就是事情的全過(guò)程.
這一點(diǎn)Python處理的很特別, 按照一般的原則, 像編碼解碼這樣的東西, 即使有問(wèn)題, 無(wú)非亂碼而已, 而Python卻一定要報(bào)錯(cuò), 現(xiàn)在整個(gè)腳本因?yàn)檫@個(gè)并不重要的因素而無(wú)法運(yùn)行了.
其實(shí)像這種場(chǎng)景, print函數(shù)即使輸出亂碼, 很多時(shí)候并不會(huì)影響整個(gè)腳本的功能, 一般的愿望是希望腳本正常運(yùn)行下去.
這實(shí)際也是大部分平臺(tái)的處理方式.
那么怎樣即能夠輸出又不影響閱讀呢?
這里推薦一種方法
print ("title: " , unicode_str.encode('gbk', 'backslashreplace').decode('gbk', 'backslashreplace'))
輸出結(jié)果是
title: how to create a windows service in python \xab Python recipes \xab ActiveState Code - Google Chrome
先encode, 用backslashreplace處理特殊字符, 完成之后得到的字節(jié)流中特殊字符被轉(zhuǎn)義字符取代了, 然后再decode為unicode, 該unicode交給print的時(shí)候, 其中的特殊字符已經(jīng)變成可以用gbk表示的東西了, 其實(shí)就是用對(duì)應(yīng)的數(shù)字.
其實(shí)這本來(lái)應(yīng)該是我預(yù)想中的應(yīng)有的默認(rèn)行為, 但是現(xiàn)在必須自己手動(dòng)處理. 更何況處理的手段還非常的ugly, 如果碰到大量的地方需要修改, 又或者需要print復(fù)合數(shù)據(jù)結(jié)構(gòu), 例如print list 或者dictionary, 或者pair之類的. 必須找更好的解決辦法, 例如改變系統(tǒng)encode的時(shí)候的默認(rèn)error handling, 不要用'strict'. 既然有默認(rèn)配置, 按理應(yīng)該是可以修改的, 不過(guò)還不知道怎么去做, 也找不到相關(guān)的文檔.
總結(jié)
以上是生活随笔為你收集整理的python 输出字符串编码_Python print 字符串编码问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python画饼状图的包_Python数
- 下一篇: mysqlsql varchar类型只取