Python print報ascii編碼異常的靠譜解決辦法


之前遇到此異常UnicodeEncodeError: 'ascii' codec can't encode characters...,都是用這種方式解決:sys.setdefaultencoding('utf-8')

今天看到如下文章,闡述了此方式的弊端:

http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

但此文章只考慮了未使用第三方庫的情況下的解決辦法,而第三方庫里如果也有print的話,就束手無策了,總不能把第三方的所有print都加上encode吧。

另外此文中說的修改編碼為utf8的隱患,其實都是因為沒有使用unicode字符串或兩種字符串混用而已,如果項目中規定只可使用u'unicode字符串',上述隱患即可基本避免。歸根結底最大的風險就是第三方庫的不可控,print編碼和unicode字符串都不可控,所以不能使用setdefaultencoding。

 

我這次是在用Java啟動python時,print中文,就會報ascii的異常,我發現此種情況下sys.stdout.encoding其實為None,而Ubuntu中普通命令行時此變量則是UTF-8。

那如何修改sys.stdout.encoding呢?(直接修改會報錯TypeError: readonly attribute)

所以最終找到http://www.macfreek.nl/memory/Encoding_of_Python_stdout

python2修改方式(python3略不同,原文中也有寫)

1 if sys.stdout.encoding != 'UTF-8':
2     sys.stdout = codecs.getwriter('utf-8')(sys.stdout, 'strict')
3 if sys.stderr.encoding != 'UTF-8':
4     sys.stderr = codecs.getwriter('utf-8')(sys.stderr, 'strict')

這樣就完美解決輸出中文時的ascii編碼異常了,而且也不用重新設置sys的默認編碼。

 

后記:

理想很豐滿,現實很骨感,有的時候還是要用setdefaultencoding的。。。

比如不僅是print,還涉及到遍歷文件,並且要寫結果文件時,在shell下運行正常,可能用java啟動的python就會報編碼問題,如果不改java那邊,可能就要選擇setdefaultencoding了,因為如果兼容了java,可能shell下又會報編碼問題了,按下葫蘆浮起瓢。當然如果把相關幾個涉及編碼的地方包個函數,在里面根據情況來切換也行,如果時間允許也可以考慮。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM