Głównym źródłem problemów miałem Praca z ciągami znaków Unicode jest kiedy wymieszać kodowanie UTF-8 ciągi Unicode One.
Weźmy na przykład następujące skrypty.
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
Wyjście działa python one.py
jest:
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)
W tym przykładzie two.name
jest łańcuchem UTF-8 (nie unicode), ponieważ nie importował unicode_literals
i one.name
to ciąg znaków Unicode. Kiedy miksujesz oba, python próbuje dekodować zakodowany ciąg (zakładając, że jest to ASCII) i przekonwertować go do Unicode i nie powiedzie się. To zadziałałoby, gdybyś zrobił print name + two.name.decode('utf-8')
.
To samo może się zdarzyć, jeśli zakodujesz łańcuch i spróbuj go później połączyć. Na przykład to działa:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
wyjściowa:
DEBUG: <html><body>helló wörld</body></html>
Ale po dodaniu import unicode_literals
to nie:
# 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
wyjściowy:
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)
Nie powiedzie się, ponieważ 'DEBUG: %s'
jest ciągiem znaków Unicode i dlatego python próbuje zdekodować html
. Kilka sposobów naprawienia drukowania: albo robisz print str('DEBUG: %s') % html
lub print 'DEBUG: %s' % html.decode('utf-8')
.
Mam nadzieję, że pomoże to zrozumieć potencjalne błędy podczas używania ciągów Unicode.
Proponuję pójść z rozwiązaniami 'decode()' zamiast rozwiązań 'str()' lub 'encode()': im częściej używasz obiektów Unicode, tym wyraźniejszy jest kod, ponieważ to, czego chcesz, to manipulować ciągami znaków, a nie tablicami z zewnętrznie domniemanym kodowaniem. – EOL
Napraw swoją terminologię.'gdy miksowane są ciągi zakodowane za pomocą UTF-8 z UTF-8 w formacie Unicode' oraz Unicode i nie mają 2 różnych kodowań; Unicode jest standardem, a UTF-8 jest jednym z definiowanych przez niego kodowań. – Kos
@Kos: Myślę, że on oznacza mieszanie "zakodowanych w UTF-8 łańcuchów" * obiektów * z unikodami (stąd dekodowane) * obiektami *. Pierwszy jest typu 'str', drugi to typ' unicode'. Będąc różnymi obiektami, problem może powstać, jeśli spróbujesz je podsumować/połączyć/interpolować – MestreLion