2017-06-27 62 views
0

我有些離開這裏選擇...的Windows CMD:管道蟒蛇3.5 PY文件結果的作品,但pyinstaller的exe導致UnicodeEncodeError

# -*- coding: utf-8 -*- 
print(chr(246) + " " + chr(9786) + " " + chr(9787)) 
print("End.") 

當我運行上面我的Win7 cmd窗口中提到的代碼,我得到的結果取決於我調用的方式:

python.exe utf8.py 
-> ö ☺ ☻ 

python.exe utf8.py >test.txt 
-> ö ☺ ☻ (in file) 

utf8.exe 
-> ö ☺ ☻ 

utf8.exe >test.txt 
RuntimeWarning: sys.stdin.encoding == 'utf-8', whereas sys.stdout.encoding == 'cp1252', readline hook consumer may assume they are the same 
Traceback (most recent call last): 
    File "Development\utf8.py", line 15, in <module> 
    print(chr(246) + " " + chr(9786) + " " + chr(9787)) 
    File "C:\python35\lib\encodings\cp1252.py", line 19, in encode 
    return codecs.charmap_encode(input,self.errors,encoding_table)[0] 
UnicodeEncodeError: 'charmap' codec can't encode character '\u263a' in position 

與win_unicode_console瞎搞也沒有幫助。最後,我得到了同樣的結果。

PYTHONIOENCODING=utf-8 

設置。但似乎,在使用時PyInstaller,參數爲stdout.encoding忽略:

print(sys.stdout.encoding) 
print(sys.stdout.isatty()) 
print(locale.getpreferredencoding()) 
print(sys.getfilesystemencoding()) 
print(os.environ["PYTHONIOENCODING"]) 

輸出:

python.exe utf8.py > test.txt 
utf-8 
False 
cp1252 
mbcs 
utf-8 

utf8.exe >test.txt 
cp1252 
False 
cp1252 
mbcs 
utf-8 

的問題是:如何發生的呢?而且:我該如何解決這個問題?

codecs.getwriter([something])(sys.stdout) 

似乎氣餒,因爲它可能導致破碎的輸出模塊。或者是否有可能強迫utf-8以防我們檢查了tty?更好:如何解決PyInstaller中的問題?

在此先感謝...

+1

我不知道如何解決PyInstaller的可執行文件,它忽略了'PYTHONIOENCODING',並且似乎使用了非tty的默認編碼。但是你可以輕鬆地重新綁定'sys.stdout'。例如,'sys.stdout = open(sys.stdout.fileno(),'w',encoding ='utf-8',closefd = False)'。 – eryksun

+0

謝謝!這適用於測試場景。只要我有時間建立(和測試)常規代碼庫,我會盡快發佈狀態! :) – Bigfoot29

回答

1

由於eryksun,以下解決方法工作:

STDOUT_ENCODING = str(sys.stdout.encoding) 
try: 
    PYTHONIOENCODING = str(os.environ["PYTHONIOENCODING"]) 
except: 
    PYTHONIOENCODING = False 

# Remark: In case the stdout gets modified, it will only append all information 
# that has been written into the pipe until that very moment. 
if sys.stdout.isatty() is False: 
    print("Program is running in piping mode. (sys.stdout.isatty() is " + str(sys.stdout.isatty()) + ".)") 
    if PYTHONIOENCODING is not False: 
     print("PYTHONIOENCODING is set to a value. ('" + str(PYTHONIOENCODING) + "')") 
     if str(sys.stdout.encoding) != str(PYTHONIOENCODING): 
      print("PYTHONIOENCODING is differing from stdout encoding. ('" + str(PYTHONIOENCODING) + "' != '" + STDOUT_ENCODING + "'). This should normally not happen unless the PyInstaller setup is still broken. Setting hard utf-8 workaround.") 
      sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8', closefd=False) 
      print("PYTHONIOENCODING was differing from stdout encoding. ('" + str(PYTHONIOENCODING) + "' != '" + STDOUT_ENCODING + "'). This should normally not happen unless PyInstaller is still broken. Setting hard utf-8 workaround. New encoding: '" + str(PYTHONIOENCODING) + "'.", "D") 
     else: 
      print("PYTHONIOENCODING is equal to stdout encoding. ('" + str(PYTHONIOENCODING) + "' == '" + str(sys.stdout.encoding) + "'). - All good.") 
    else: 
     print("PYTHONIOENCODING is set False. ('" + str(PYTHONIOENCODING) + "'). - Nothing to do.") 
else: 
    print("Program is running in terminal mode. (sys.stdout.isatty() is " + str(sys.stdout.isatty()) + ".) - All good.") 

試圖建立一個新的PyInstaller-環境,看看是否從一開始就修復它未來。