簡體   English   中英

雖然我正在做str.decode(),但Python會拋出UnicodeEncodeError。 為什么?

[英]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中從JSON獲取字符串對象而不是Unicode對象?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM