La principale fonte di problemi che ho avuto che lavorano con le stringhe Unicode è quando si mescolano stringhe UTF-8 codificati con quelli unicode.
Ad esempio, considerare i seguenti script.
two.py
# encoding: utf-8
name = 'helló wörld from two'
one.py
# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name
L'uscita di esecuzione python one.py
è:
Traceback (most recent call last):
File "one.py", line 5, in <module>
print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)
In questo esempio, two.name
corda è un utf-8 codificato (non unicode) poiché non importava unicode_literals
e one.name
è una stringa unicode. Quando si mescolano entrambi, python prova a decodificare la stringa codificata (assumendo che sia ascii) e convertirla in unicode e fallisce. Funzionerebbe se lo facessi print name + two.name.decode('utf-8')
.
La stessa cosa può succedere se si codifica una stringa e si prova a mescolarli in un secondo momento. Per esempio, questo funziona:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
uscita:
DEBUG: <html><body>helló wörld</body></html>
Ma dopo l'aggiunta del import unicode_literals
non è così:
# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
uscita:
Traceback (most recent call last):
File "test.py", line 6, in <module>
print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)
Fallisce perché 'DEBUG: %s'
è una stringa unicode e quindi python prova a decodificare html
. Un paio di modi per risolvere la stampa stanno facendo print str('DEBUG: %s') % html
o print 'DEBUG: %s' % html.decode('utf-8')
.
Spero che questo ti aiuti a capire i potenziali trucchi quando usi stringhe Unicode.
Suggerirei di andare con le soluzioni 'decode()' invece delle soluzioni 'str()' o 'encode()': più spesso usi gli oggetti Unicode, più chiaro è il codice, poiché ciò che vuoi è manipola stringhe di caratteri, non matrici di byte con una codifica implicita esternamente. – EOL
Si prega di correggere la terminologia.'quando si mischiano le stringhe codificate utf-8 con quelle unicode' UTF-8 e Unicode e non 2 diverse codifiche; Unicode è uno standard e UTF-8 è una delle codifiche che definisce. – Kos
@Kos: Penso che voglia dire mixare "utf-8 encoded stringhe" * objects * con unicode (quindi decodificato) * oggetti *. Il primo è di tipo 'str', il secondo è tipo' unicode'. Essendo oggetti diversi, può sorgere un problema se si tenta di sommare/concatenare/interpolare loro – MestreLion