【轉】Python3—UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1


轉自:https://blog.csdn.net/AckClinkz/article/details/78538462

環境

>>> import sys
>>> print(sys.version)
'3.6.0 |Anaconda 4.3.1 (64-bit)| (default, Dec 23 2016, 12:22:00) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]'
  • 1
  • 2
  • 3

問題描述

今天在使用python3的時候,報錯信息

Traceback (most recent call last):
  File "tmp.py", line 3, in <module>
    print(a)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
  • 1
  • 2
  • 3
  • 4

報錯代碼可簡化為

a = b'\xe5\x94\xb1\xe6\xad\x8c'
a = a.decode("utf-8")
print(a)
  • 1
  • 2
  • 3

問題分析

本節介紹問題的分析過程,如果想看解決辦法,可以直接看一下節。

網上解釋

網上給出的解釋:錯誤的使用decode和encode方法會出現這種異常。例如使用decode方法將Unicode字符串轉化的時候:

s = u'中文'
s.decode('utf-8')
print s
  • 1
  • 2
  • 3

但是將這個例子放到python3環境中,會報錯

Traceback (most recent call last):
  File "tmp_2.py", line 4, in <module>
    s.decode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
  • 1
  • 2
  • 3
  • 4

熟悉python歷史的朋友會知道,為了解決編碼問題,在python3中,所有的字符串都是使用Unicode編碼,統一使用str類型來保存,而str類型沒有decode方法,所以網上給出的方向並不適合我的問題。

字符編碼

為了確定是否是字符編碼的問題,我換了一台python3機器,測試了一下

>>>a = b'\xe5\x94\xb1\xe6\xad\x8c'
>>>a = a.decode("utf-8")
>>>print(a)
唱歌
  • 1
  • 2
  • 3
  • 4

完全沒有問題,正常輸出,排除字符編碼和代碼失誤。

輸出

既然字符編碼、代碼都沒有錯,那么問題肯定出在print上面。這時我開始關注錯誤信息中的ascii。因為在一般python3環境中,輸出時會將Unicode轉化為utf-8。為了解開這個疑惑,查看了輸出編碼

>>>import sys
>>>sys.stdout.encoding
'ANSI_X3.4-1968'
  • 1
  • 2
  • 3

竟然是ANSI_X3.4-1968,所以任何中文都會報錯。哈哈,終於定位問題啦。

解決方案

定位問題后,解決辦法就很簡單啦,有兩種方法

運行python的時候加上PYTHONIOENCODING=utf-8,即

PYTHONIOENCODING=utf-8 python your_script.py
  • 1
  • 重新定義標准輸出

標准輸出的定義如下

sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
  • 1

打印日志的方法

sys.stdout.write("Your content....")
  • 1

總結

通過分析這個問題,進一步加深了對python3的了解。另外,希望各位看官批評指正!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM