2009-09-24 21 views
16

假設一個人不能使用print(從而享受自動編碼檢測的好處)。因此,我們留下了sys.stdout。但是,sys.stdoutnot do any sensible encoding是如此愚蠢。通過Python中的sys.stdout編寫unicode字符串

現在一個讀取Python的wiki頁面PrintFails,去嘗試一下下面的代碼:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \ 
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); 

但是這也不能正常工作(至少在Mac)。看到爲什麼:

>>> import locale 
>>> locale.getpreferredencoding() 
'mac-roman' 
>>> sys.stdout.encoding 
'UTF-8' 

(UTF-8是什麼人的終端了解)。

所以一個改變了上述的代碼:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \ 
    sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout); 

現在Unicode字符串被適當地發送到sys.stdout,因此正確打印在終端上(sys.stdout所連接的終端)。

這是在sys.stdout中寫入unicode字符串的正確方法還是我應該做其他事情?

編輯:有時候 - 比如,輸出管道,以less當 - sys.stdout.encodingNone。在這種情況下,上面的代碼將失敗。

+0

S /我的/爲了一致性 – icedwater 2014-07-11 06:14:28

回答

3

我不清楚你爲什麼不能打印;但是,假設是這樣,這種方法對我來說很合適。

+1

我不能使用'print'的一個原因是爲了避免額外的空間'print'打印。看看使用'這裏sys.stdout':http://stackoverflow.com/questions/1396820/apt-like-column-output-python-library/1397382#1397382 – 2009-09-24 19:52:44

+3

你可以建立完整的生產線,然後打印他們。 – 2009-09-24 20:04:01

+0

Bravo!是的,在這種情況下,我可以用'print' – 2009-09-24 20:13:57

10

最好的辦法是檢查你是否直接連接到終端。如果是,請使用終端的編碼。否則,請使用系統首選編碼。

if sys.stdout.isatty(): 
    default_encoding = sys.stdout.encoding 
else: 
    default_encoding = locale.getpreferredencoding() 

總是允許用戶指定她想要的任何編碼也是非常重要的。通常我會將它作爲命令行選項(如-e ENCODING),並使用optparse模塊進行解析。

另一件好事是用而不是用自動編碼器覆蓋sys.stdout。創建您的編碼器並使用它,但單獨留下sys.stdout。您可以導入將編碼字節串直接寫入sys.stdout的第三方庫。

8

有一個可選的環境變量「PYTHONIOENCODING」,它可以設置爲所需的默認編碼。這將是一種以與所有Python一致的方式抓取用戶期望的編碼的方式。它被埋在Python手冊here中。

27
export PYTHONIOENCODING=utf-8 

會做這項工作,但不能在Python本身設置...

我們能做的就是驗證,如果沒有設置,並告訴用戶與呼叫腳本之前設置它是什麼:

if __name__ == '__main__': 
    if (sys.stdout.encoding is None): 
     print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout." 
     exit(1) 
+0

非常感謝,爲我工作。 – Kino 2017-02-14 08:19:15

6

這是我在我的應用程序正在做的:

sys.stdout.write(s.encode('utf-8'))

這是用於從讀出的argv UTF-8名完全相反的修復:

for file in sys.argv[1:]: 
    file = file.decode('utf-8') 

這是非常醜陋(恕我直言),因爲它迫使你使用UTF-8的工作..這是Linux/Mac的常態,而不是在Windows ...爲我工作反正:)

相關問題