[英]Python throws UnicodeEncodeError although I am doing str.decode(). Why?
考慮這個功能:
def escape(text):
print repr(text)
escaped_chars = []
for c in text:
try:
c = c.decode('ascii')
except UnicodeDecodeError:
c = '&{};'.format(htmlentitydefs.codepoint2name[ord(c)])
escaped_chars.append(c)
return ''.join(escaped_chars)
它應該通過相應的htmlentitydefs轉義所有非ascii字符。 不幸的是python拋出
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 0: ordinal not in range(128)
當變量text
包含其repr()
為u'Tam\\xe1s Horv\\xe1th'
的字符串時。
但是,我不使用str.encode()
。 我只使用str.decode()
。 我錯過了什么嗎?
這是一個誤導性的錯誤報告,它來自python處理de /編碼過程的方式。 你試圖第二次解碼一個已經解碼過的字符串,這會混淆Python函數,它會讓你反過來混淆你的報復! ;-)編碼/解碼過程據我所知,由編解碼器模塊進行。 在某處,存在這種誤導性的異常消息的起源。
您可以自己檢查:或者
u'\x80'.encode('ascii')
要么
u'\x80'.decode('ascii')
將拋出Unicode 編碼錯誤,其中a
u'\x80'.encode('utf8')
不會,但是
u'\x80'.decode('utf8')
再一次!
我猜你對編碼和解碼的含義感到困惑。 簡單來說:
decode encode
ByteString (ascii) --------> UNICODE ---------> ByteString (utf8)
codec codec
但為什么decode
方法會出現codec
參數? 好吧,底層函數無法猜測ByteString編碼的編解碼器,因此提示它將codec
作為參數。 如果沒有提供,它假定您的意思是隱式使用sys.getdefaultencoding()
。
所以當你使用c.decode('ascii')
你a)有一個(編碼的)ByteString(這就是為什么你使用解碼)b)你想得到一個unicode表示對象(這就是你使用解碼的對象)和c )編碼ByteString的編解碼器是ascii。
另見: https : //stackoverflow.com/a/370199/1107807
http://docs.python.org/howto/unicode.html
http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
http://www.stereoplex.com/blog/python-unicode-and-unicodedecodeerror
你傳遞的字符串已經是unicode了。 因此,在Python可以decode
進行decode
之前,它必須實際對其進行編碼 - 並且默認情況下使用ASCII編碼進行編碼。
編輯以添加它取決於您想要做什么。 如果您只想將帶有非ASCII字符的unicode字符串轉換為HTML編碼表示,則可以在一次調用中執行: text.encode('ascii', 'xmlcharrefreplace')
。
當我遇到這個問題時,這個答案總是對我有用:
def byteify(input):
'''
Removes unicode encodings from the given input string.
'''
if isinstance(input, dict):
return {byteify(key):byteify(value) for key,value in input.iteritems()}
elif isinstance(input, list):
return [byteify(element) for element in input]
elif isinstance(input, unicode):
return input.encode('utf-8')
else:
return input
Python有兩種類型的字符串:字符串( unicode
類型)和字節串( str
類型)。 您粘貼的代碼在字節字符串上運行。 您需要一個類似的函數來處理字符串。
也許這個:
def uescape(text):
print repr(text)
escaped_chars = []
for c in text:
if (ord(c) < 32) or (ord(c) > 126):
c = '&{};'.format(htmlentitydefs.codepoint2name[ord(c)])
escaped_chars.append(c)
return ''.join(escaped_chars)
我確實想知道這兩種功能是否真的對你有用。 如果是我,我會選擇UTF-8作為結果文檔的字符編碼,以字符串形式處理文檔(不用擔心實體),並執行content.encode('UTF-8')
作為在將其交付給客戶之前的最后一步。 根據所選的Web框架,您甚至可以直接向API提供字符串,並讓它弄清楚如何設置編碼。
我在這個網站找到了解決方案
reload(sys) sys.setdefaultencoding("latin-1") a = u'\xe1' print str(a) # no exception
decode
str
沒有意義。
我想你可以檢查ord(c)>127
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.