2014-06-29 10 views
28

quando provo a concatenarlo, ottengo l'errore UnicodeDecodeError quando il campo contiene 'ñ' o '' '. Se il campo che contiene "ñ" o "" è l'ultimo non ottengo alcun errore.UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xc3 in posizione 23: ordinale non compreso nell'intervallo (128)

#... 

nombre = fabrica 
nombre = nombre.encode("utf-8") + '-' + sector.encode("utf-8") 
nombre = nombre.encode("utf-8") + '-' + unidad.encode("utf-8") 

#... 

return nombre 

qualche idea? Grazie molto!

+0

Possibile duplicato di [Python - 'ascii' codec non può decodificare byte] (http://stackoverflow.com/questions/ 9644099/python-ascii-codec-cant-decode-byte) – bummi

risposta

36

Si sta codificando su UTF-8, quindi su -encoding su UTF-8. Python può fare solo se prima decodifica di nuovo in Unicode, ma deve utilizzare il codec predefinito ASCII:

>>> u'ñ' 
u'\xf1' 
>>> u'ñ'.encode('utf8') 
'\xc3\xb1' 
>>> u'ñ'.encode('utf8').encode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128) 

Non tenere la codifica; lasciare la codifica UTF-8 all'ultimo momento possibile. Concatena invece i valori Unicode.

È possibile utilizzare str.join() (o, meglio, unicode.join()) qui per concatenare i tre valori con trattini tra:

nombre = u'-'.join(fabrica, sector, unidad) 
return nombre.encode('utf-8') 

ma anche la codifica qui potrebbe essere troppo presto.

Regola del pollice: decodificare nel momento in cui si riceve il valore (se non sono già forniti da un'API i valori Unicode), codificare solo quando è necessario (se l'API di destinazione non gestisce direttamente i valori Unicode).

+0

Penso che la regola generale qui sia il punto chiave. Potrebbe essere formulato: "codifica e decodifica solo sui limiti dell'API e solo se è necessario". –

0

Questa soluzione ha funzionato per il mio caso

cambiamento

my_str = str(my_str) #Basically it removes encoding 
+0

'str (my_str)' potrebbe non risolverlo: 'UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xc3 nella posizione 1253: ordinal non nel range (128)' – rafaelvalle

1

Quando si riceve una UnicodeEncodeError, vuol dire che da qualche parte nel codice di convertire direttamente una stringa di byte ad uno unicode. Di default in Python 2 utilizza la codifica ascii e la codifica utf8 in Python3 (entrambi possono fallire perché non tutti i byte sono validi in entrambe le codifiche)

Per evitare ciò, è necessario utilizzare la decodifica esplicita.

Se nel file di input si dispone di 2 codifiche diverse, una accetta byte (ad esempio UTF8 e Latin1), è possibile provare prima a convertire una stringa e utilizzare la seconda se si verifica un errore UnicodeDecodeError.

def robust_decode(bs): 
    '''Takes a byte string as param and convert it into a unicode one. 
First tries UTF8, and fallback to Latin1 if it fails''' 
    cr = None 
    try: 
     cr = bs.decode('utf8') 
    except UnicodeDecodeError: 
     cr = bs.decode('latin1') 
    return cr 

Se non si conosce la codifica originale e non si cura per caratteri non ASCII, è possibile impostare il errors parametro facoltativo del metodo decode a replace. Qualsiasi offendere byte sarà sostituito (dalla documentazione libreria standard):

Replace with a suitable replacement character; Python will use the official U+FFFD REPLACEMENT CHARACTER for the built-in Unicode codecs on decoding and ‘?’ on encoding.

bs.decode(errors='replace') 
+0

Questa non è direttamente una risposta alla domanda presente ma a [ quello] (http://stackoverflow.com/q/42410322/3545273) che è stato chiuso come duplicato.Almeno è correlato a causa di un errore UnicodeDecodeError e gli utenti che cercano l'errore troveranno questa risposta ... –

Problemi correlati