天天看點

《Python Cookbook(第2版)中文版》——1.22 在标準輸出中列印Unicode字元

本節書摘來自異步社群《python cookbook(第2版)中文版》一書中的第1章,第1.22節,作者[美]alex martelli , anna martelli ravenscrof , david ascher ,高鐵軍 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

任務

你想将unicode字元串列印到标準輸出中(比如為了調試),但是這些字元串并不符合預設的編碼。

解決方案

通過python标準庫中的codecs子產品,将sys.stdout流用轉換器包裝起來。比如,如果你知道輸出會被列印到一個終端,而且該終端以iso-8859-1的編碼顯式字元,可以這樣編寫代碼:

讨論

unicode涵蓋極廣,全世界的語言字元都在unicode的表示範圍之内,另外,unicode字元串的内部表示也與unicode使用者沒有關系。一個用于處理位元組的檔案流,比如sys.stdout,都有自己的編碼。可以通過修改site子產品改變其預設的編碼,該檔案流将對新檔案使用新編碼。不過,這樣也需要完全改變你的python安裝,而且其他一些程式則可能會被搞亂,它們依然會按照你原先的編碼設定工作(一般是典型的python标準編碼,ascii)。是以,這種修改并不值得推薦。

本節的方法則用了一個技巧:将sys.stdout綁定到一個使用unicode輸入和iso-8859-1(也就是latin-1)輸出的流。這種方法并不改變之前sys.stdout上的任何編碼,如下面代碼所示。首先,我們用一個變量指向原來的基于ascii的sys.stdout:

然後,我們可以建立一個unicode字元串,這個字元串通常情況下是不能通過sys.stdout輸出的:

如果這個操作沒有出現錯誤,那是因為python認為它知道你的“終端”用了什麼編碼(特别是,如果你的“終端”是idle—python所附的免費的開發環境,python極有可能能夠确認正确的編碼)。如果出現了錯誤,或者沒有提示錯誤,但是輸出的字元卻不是你期望的,那是因為你的“終端”使用了utf-8編碼,而python卻不知道。如果屬于後者的情況,可以用codecs流對sys.stdout進行包裝以解決utf-8編碼問題,将sys.stdout綁定到被封裝過的流,然後重新試一次:

這個方法隻在你的“終端”、終端模拟器或者其他類型的互動式python解釋視窗支援utf-8編碼時才有效,而且具有極強的字元表現力,能夠顯示出任何需要的字元。如果沒有這樣的程式或裝置,可以在網際網路上找一個适用于你的平台的免費的程式。

python會嘗試确認你的“終端”的編碼,并把編碼的名字存在sys.stdout.encoding中作為一個屬性。有時(但不是總是),它能夠判斷出正确的編碼。idle已經對sys.stdout進行了包裝,正如本節解決方案的方法一樣,是以,在python的互動式環境之下,可以直接列印出unicode字元串。