Il problema più probabile è che json_obj["description"]
è in realtà un codice str
codificato in UTF-8, non uno . Quindi, quando si prova a in un file wrapper codecs
, Python deve decodificarlo da str
a unicode
in modo che possa ricodificarlo. E quella è la parte che non riesce, perché quella decodifica automatica utilizza sys.getdefaultencoding()
, che è 'ascii'
.
Ad esempio:
>>> f = codecs.open('emoji.txt', 'w+', encoding='utf-8')
>>> e = u'\U0001f1ef'
>>> print e
>>> e
u'\U0001f1ef'
>>> f.write(e)
>>> e8 = e.encode('utf-8')
>>> e8
'\xf0\x9f\x87\xaf'
>>> f.write(e8)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
Ci sono due possibili soluzioni qui.
Innanzitutto, è possibile decodificare in modo esplicito tutto a unicode
il prima possibile. Non sono sicuro da dove provenga il tuo json_obj
, ma sospetto che non sia in realtà lo stdlib json.loads
, perché per impostazione predefinita, questo ti da sempre chiavi e valori unicode
. Quindi, la sostituzione di qualsiasi cosa tu stia utilizzando per JSON con le funzioni stdlib probabilmente risolverà il problema.
In secondo luogo, è possibile lasciare tutto come UTF-8 str
oggetti e rimanere in modalità binaria. Se sai di avere UTF-8 ovunque, solo il open
il file invece di codecs.open
e scrivi senza alcuna codifica.
Inoltre, si dovrebbe prendere in seria considerazione utilizzando io.open
invece di codecs.open
. Ha una serie di vantaggi, tra cui:
- Solleva un'eccezione invece di fare la cosa sbagliata se si passa valori errati.
- Spesso più veloce.
- Inoltrabile con Python 3.
- Ha una serie di correzioni di bug che non verranno mai ritrasportate a
codecs
.
L'unico svantaggio è che non è retrocompatibile con Python 2.5. A meno che ciò sia importante per te, non utilizzare codecs
.
È 'json_obj [" description "]' a 'unicode' o a' str'? Se quest'ultimo, in che codifica è? Inoltre, puoi 'stampare repr (json_obj [" description "])' subito prima dell'errore, in modo che possiamo vedere cosa stai effettivamente cercando di stampare? – abarnert
Inoltre, da dove proviene 'json_obj'? Il nome implica il modulo stdlib 'json', ma il fatto che le chiavi e i valori siano apparentemente' str' implica che non sia ... – abarnert