La principale source de problèmes que j'ai rencontrés en travaillant avec des chaînes Unicode est lorsque vous mélangez des chaînes encodées en utf-8 avec des chaînes Unicode.
Par exemple, considérez les scripts suivants.
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
Le résultat de l'exécution python one.py
est:
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)
Dans cet exemple, two.name
est une chaîne encodée en utf-8 (pas unicode) car elle n'a pas été importée unicode_literals
, et one.name
est une chaîne unicode. Lorsque vous mélangez les deux, python essaie de décoder la chaîne codée (en supposant qu'elle est ascii) et de la convertir en Unicode et échoue. Cela fonctionnerait si vous le faisiez print name + two.name.decode('utf-8')
.
La même chose peut arriver si vous encodez une chaîne et essayez de les mélanger plus tard. Par exemple, cela fonctionne:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
Production:
DEBUG: <html><body>helló wörld</body></html>
Mais après avoir ajouté le, import unicode_literals
il ne fait PAS:
# 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
Production:
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)
Il échoue car il 'DEBUG: %s'
s'agit d'une chaîne Unicode et par conséquent, python essaie de décoder html
. Deux façons de corriger l'impression sont soit de faire print str('DEBUG: %s') % html
ou print 'DEBUG: %s' % html.decode('utf-8')
.
J'espère que cela vous aidera à comprendre les pièges potentiels lors de l'utilisation de chaînes Unicode.
decode()
solutions au lieu des solutionsstr()
ouencode()
: plus vous utilisez souvent des objets Unicode, plus le code est clair, car ce que vous voulez, c'est manipuler des chaînes de caractères, pas des tableaux d'octets avec un encodage implicite externe.