2015-09-30 50 views
3

我已經讀完了這一點:Python 2.7版的Unicode混亂再次

Setting the correct encoding when piping stdout in Python

我試圖堅持使用經驗法則:「總是在內部使用Unicode解碼收到的東西,編碼你送什麼

因此,這裏是我的主要文件。

# coding: utf-8 

import os 
import sys 

from myplugin import MyPlugin 
if __name__ == '__main__': 
    c = MyPlugin() 
    a = unicode(open('myfile.txt').read().decode('utf8')) 
    print(c.generate(a).encode('utf8')) 

是什麼讓我心煩的是:

  • 我讀了一個utf8文件,所以我解碼它。
  • 然後我強迫其轉換爲Unicode這給unicode(open('myfile.txt').read().decode('utf8'))
  • 然後我試着將它輸出到終端
  • 在我的Linux外殼,我需要重新編碼爲utf8,並我想這是正常因爲我一直在unicode字符串上工作,然後輸出它,我必須重新編碼它在utf8(糾正我,如果我在這裏是錯誤的)
  • 當我在Windows下使用Pycharm運行它,它是兩次utf8編碼,這給了我像agréable, déjÃ的東西。所以,如果我刪除encode('utf8')(更改最後一行print(c.generate(a))那麼它與Pycharm,但不會再使用Linux,在那裏我得到工作:布拉布拉你知道問題'ascii' codec can't encode character u'\xe9' in position

如果我嘗試在命令行:

  • 的Linux /殼SSH:import sys sys.stdout.encoding我得到'UTF-8'
  • 的Linux /殼在我的代碼import sys sys.stdout.encoding我得到None WTF?
  • 的Windows/Pycharm:import sys sys.stdout.encoding我得到'windows-1252'

什麼是實現代碼,以便它可以在這兩種環境的最佳方法是什麼?

+0

我喜歡使用[codecs](https://docs.python.org/2.7/library/codecs.html)在'utf-8'中打開文件,並且始終在代碼中使用'u「anystring」' 。當然,該文件必須保存在utf-8中。那時我沒有太多問題。如果您使用的是IDE,則必須將其配置爲默認讀取utf-8,也可以使用shell。這可能對你沒有任何幫助,但這是我避免陷入很多編碼問題的方法。 – colidyre

回答

0

你是哲學是正確的,但你過於複雜的事情,使你的代碼變得脆弱。

以文本模式打開文件以自動轉換爲Unicode。然後在沒有編碼的情況下打印 - 打印應該是正確的編碼。

如果您的Linux環境設置不正確,請在您的Linux環境變量(export PYTHONIOENCODING=utf-8)中設置PYTHONIOENCODING=utf-8以解決打印期間的任何問題。您應該考慮將您的語言環境設置爲UTF-8變體,例如en_GB.UTF-8,以避免必須定義PYTHONIOENCODING

PyCharm應該不加修改地工作。

您的代碼應該是這樣的:

import os 
import sys 
import io 

from myplugin import MyPlugin 

if __name__ == '__main__': 
    c = MyPlugin() 
    # t is the default 
    with io.open('myfile.txt', 'rt', encoding='utf-8') as myfile: 
     # a is now a Unicode string 
     a = myfile.read() 

    result = c.generate(a) 
    print result 

如果你使用的是Python 3.x中,從io.open()下降import ioio.

0
unicode(open('myfile.txt').read().decode('utf8')) 

無需與unicode包裹,因爲str.decode結果已經unicode

print(c.generate(a).encode('utf8')) 

無需encode因爲Python將編碼根據終端的編碼字符串本身。

所以這是做

print(c.generate(a)) 

正確的方法你得到'ascii' codec can't encode character u'\xe9' in position因爲你的Linux終端具有ascii編碼,因此它不可能爲Python打印Unicode字符給它。

https://wiki.python.org/moin/PrintFails

我建議你固定終端(環境),而不是代碼。你不應該依賴於終端編碼,特別是通常你將這些信息打印到文件中。

如果你仍然想將它打印到支持ASCII任何終端,你可以使用str.encode('unicode-escape')

>>> print(u'щхжы'.encode('unicode-escape')) 
\u0449\u0445\u0436\u044b 

但是,這將不被人類可讀性很強,所以我不明白這一點。

+0

你說我的終端有ascii編碼,所以我不明白爲什麼,如果我在終端啓動python作爲命令行,並嘗試sys.stdout.encoding我得到'UTF-8',而如果我啓動它與「python mymain.py」,我得到「None」作爲編碼? –

+0

如果我在shell中通過python命令行嘗試你的示例,'print u「\ u03A9」'工作,而在主文件中,它不起作用。這個問題從哪裏來? –

+0

好的找到了解決方案:我的最後一行應該是'print(c.generate(a).encode(sys.stdout.encoding))' –