Die Hauptursache für Probleme bei der Arbeit mit Unicode-Zeichenfolgen ist das Mischen von utf-8-codierten Zeichenfolgen mit Unicode-Zeichenfolgen.
Betrachten Sie beispielsweise die folgenden Skripte.
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
Die Ausgabe von running python one.py
ist:
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 diesem Beispiel two.name
handelt es sich um eine utf-8-codierte Zeichenfolge (kein Unicode), da sie nicht importiert wurde unicode_literals
, und one.name
um eine Unicode-Zeichenfolge. Wenn Sie beide mischen, versucht Python, die codierte Zeichenfolge zu dekodieren (vorausgesetzt, es handelt sich um ASCII), und konvertiert sie in Unicode. Es würde funktionieren, wenn Sie es tun würden print name + two.name.decode('utf-8')
.
Das gleiche kann passieren, wenn Sie eine Zeichenfolge codieren und später versuchen, sie zu mischen. Zum Beispiel funktioniert dies:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
Ausgabe:
DEBUG: <html><body>helló wörld</body></html>
Aber nach dem Hinzufügen der import unicode_literals
tut es NICHT:
# 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
Ausgabe:
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)
Es schlägt fehl, weil 'DEBUG: %s'
es sich um eine Unicode-Zeichenfolge handelt und Python daher versucht, sie zu dekodieren html
. Ein paar Möglichkeiten , um den Druck zu beheben sind entweder tun print str('DEBUG: %s') % html
oder print 'DEBUG: %s' % html.decode('utf-8')
.
Ich hoffe, dies hilft Ihnen dabei, die möglichen Fallstricke bei der Verwendung von Unicode-Zeichenfolgen zu verstehen.
decode()
Lösungen anstelle derstr()
oderencode()
-Lösungen zu verwenden: Je häufiger Sie Unicode-Objekte verwenden, desto klarer ist der Code, da Sie Zeichenfolgen und keine Byte-Arrays mit einer extern implizierten Codierung bearbeiten möchten.