Unicode dizeleriyle çalışırken yaşadığım sorunların ana kaynağı, utf-8 kodlu dizeleri unicode olanlarla karıştırmanızdır.
Örneğin, aşağıdaki komut dosyalarını düşünün.
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
Koşmanın çıktısı 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)
Bu örnekte, two.nameiçe aktarılmadığı için utf-8 kodlu bir dizedir (unicode değil) unicode_literalsve one.namebir unicode dizesidir. Her ikisini de karıştırdığınızda, python kodlanmış dizenin kodunu çözmeye çalışır (ascii olduğunu varsayarak) ve onu unicode'a dönüştürür ve başarısız olur. Yapsaydın işe yarardı print name + two.name.decode('utf-8').
Bir dizeyi kodlar ve daha sonra karıştırmaya çalışırsanız aynı şey olabilir. Örneğin, bu işe yarar:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
Çıktı:
DEBUG: <html><body>helló wörld</body></html>
Ancak ekledikten sonra import unicode_literalsYAPMAZ:
# 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
Çıktı:
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)
Başarısız olur çünkü 'DEBUG: %s'bir unicode dizesidir ve bu nedenle python kodunu çözmeye çalışır html. Baskıyı düzeltmenin birkaç yolu ya yapıyor print str('DEBUG: %s') % htmlya da print 'DEBUG: %s' % html.decode('utf-8').
Umarım bu, unicode dizelerini kullanırken olası sorunları anlamanıza yardımcı olur.
decode()çözümleri yerine çözümlerle gitmenizi öneririm : Unicode nesnelerini ne kadar sık kullanırsanız, kod o kadar net olur, çünkü istediğiniz şey, harici olarak ima edilen bir kodlama ile bayt dizilerini değil, karakter dizilerini değiştirmek.str()encode()