La principale fonte di problemi che ho avuto a lavorare con le stringhe unicode è quando mescoli stringhe codificate utf-8 con stringhe unicode.
Ad esempio, considera 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'output della corsa 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
è una stringa codificata utf-8 (non Unicode) poiché non è stata importata unicode_literals
ed one.name
è una stringa Unicode. Quando mescoli entrambi, python prova a decodificare la stringa codificata (supponendo che sia ascii) e la converte in unicode e fallisce. Funzionerebbe se lo facessi print name + two.name.decode('utf-8')
.
La stessa cosa può accadere se codifichi una stringa e provi a mescolarli in un secondo momento. Ad 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
Produzione:
DEBUG: <html><body>helló wörld</body></html>
Ma dopo aver aggiunto import unicode_literals
NON:
# 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
Produzione:
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)
Non riesce perché 'DEBUG: %s'
è una stringa Unicode e quindi Python cerca di decodificare html
. Un paio di modi per correggere la stampa sono 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 le stringhe Unicode.
decode()
soluzioni invece delle soluzionistr()
oencode()
: più spesso usi oggetti Unicode, più chiaro è il codice, poiché ciò che vuoi è manipolare stringhe di caratteri, non matrici di byte con una codifica implicita esternamente.