查了一會資料得出的結論是如果你用的是python3.x,那么就最好別去設置sys.defaultencoding或者sys.stdout.encoding
記住在需要編碼的時候用encode,解碼的時候decode就可以了。。。
這個問題貌似很復雜
首先區分一下sys.stdout.encoding和sys.defaultencoding
sys.defaultencoding
sys.defaultencoding是默認的字符串轉化編碼
在python2.x版本中,字符串默認編碼是ascii,舉例來說,
a="abc"+u"bcd"
當連接一個ascii編碼的字節型字符串"abc"和一個unicode字符串bcd的時候,python調用"abc".decode(sys.getdefaultencoding())將abc轉換成unicode編碼,如果把"abc"替換成一個非ascii字符,編碼工作就會失敗,並提示UnicodeDecodeError。因為ascii字符實在是太少,顯示中文都不行,所以python提供sys.setdefaultencoding允許用戶設置默認編碼。但是在python3.0中字符串默認使用的是unicode編碼,所以sys.getdefaultencoding將會被廢棄。
那么問題可能是,我用python3想把默認編碼換成utf8,怎么辦?
2.x有方法,3.x就找不到方法了,而且很多大佬也強烈建議不要換
參考這個問題里的前兩個回答(尤其是第二個):
https://stackoverflow.com/questions/11741574/how-to-print-utf-8-encoded-text-to-the-console-in-python-3
sys.stdout.encoding
sys.stdout.encoding是終端輸出編碼,比方輸出到windows控制台使用的編碼..其實print函數就是對於sys.stdout.write()的封裝,直接sys.stdout.write()也可以輸出
在python2.x里面,可以通過設置環境變量PYTHONIOENCODING=ascii把sys.stdout.encoding改成ascii編碼,但是在python3.x里面這種方法也行不通了
關於python3.0的sys.stdout.encoding可能又要分成兩個來說,一個是windows控制台終端,一個是python的IDLE
windows控制台
對於windows控制台,python在輸出的時候通過unicode API傳送到windows控制台,如果控制台設置了字體支持該字符顯示,就會顯示出來,如果控制台不支持顯示,它就不顯示,但也不會報錯,而且還可以把它拷貝到它能顯示的地方。
python的IDLE
IDLE貌似就沒有windows控制台這么智能,不支持它就報錯。這個找不到解決辦法,但是一般都能打印的,除非你嘗試利用IDLE打印某些奇怪的字符
另外,還有一個可能是重點,python3.x默認的sys.stdout.encoding只是一個首選,比方把sys.stdout.encoding設置成ascii輸出方式,當碰到要輸出的內容是unicode編碼的時候,它會自動在sys里尋找某種合適的編碼,然后采用這種編碼,所以最后還是會以unicode編碼的形式輸出。
這樣看起來是不是,在python3.x里設置sys.stdout.encoding也沒什么用
但是如果非要設置,那么可以參考https://stackoverflow.com/a/32176732/4279,最后那句話
其他的還可以參考https://blog.csdn.net/jian3x/article/details/89442748
最后看到一個有意思的例子
分別讓windows控制台和IDLE執行print('\U0001F44D')
IDLE會報錯,UnicodeEncodeError: 'UCS-2' codec can't encode character '\U0001f44d' in position 0: Non-BMP character not supported in Tk
windows控制台會顯示兩個框框,表示顯示不了,但是可以復制粘貼到記事本是這樣一個符號👍
但試着這樣執行一下
non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)
print('\U0001F44D'.translate(non_bmp_map))
編碼我覺得我還需要研究研究,很多地方可能我理解錯了,所以最好看我帖的鏈接的原文