Twoje pytanie jest nieprawidłowe; błąd, który widzisz, nie wynika z tego, jak zbudowałeś Pythona, ale z pomieszania ciągów bajtów i ciągów Unicode.
Ciągi bajtów (np. „Foo” lub „bar” w składni Pythona) są ciągami oktetów; numery od 0-255. Ciągi znaków Unicode (np. „Foo” lub „bar”) są ciągami punktów kodu Unicode; numery od 0-1112064. Wygląda jednak na to, że interesuje Cię znak é, który (w twoim terminalu) jest sekwencją wielobajtową reprezentującą pojedynczy znak.
Zamiast tego ord(u'é')
spróbuj:
>>> [ord(x) for x in u'é']
To pokazuje, która sekwencja punktów kodowych „é” reprezentuje. Może dać ci [233] lub może dać [101, 770].
Zamiast tego chr()
odwrócić, istnieją unichr()
:
>>> unichr(233)
u'\xe9'
Ten znak może faktycznie być reprezentowany jako pojedynczy lub wiele „kodów” unicode, które same reprezentują grafem lub znaki. Może to być „ez ostrym akcentem (tj. Kod 233)” lub „e” (kod 101), a następnie „wyraźny akcent na poprzedni znak” (kod 770). Tak więc ten sam znak może być przedstawiony jako struktura danych Python u'e\u0301'
lub u'\u00e9'
.
Przez większość czasu nie powinieneś się tym przejmować, ale może to stanowić problem, jeśli iterujesz ciąg znaków Unicode, ponieważ iteracja działa według punktu kodowego, a nie według znaku rozkładającego się. Innymi słowy, len(u'e\u0301') == 2
i len(u'\u00e9') == 1
. Jeśli jest to dla Ciebie ważne, możesz przechodzić między formularzami złożonymi i rozłożonymi za pomocą unicodedata.normalize
.
Glosariusz Unicode może być pomocnym przewodnikiem do zrozumienia niektórych z tych problemów, wskazując, w jaki sposób poszczególne terminy odnoszą się do różnych części reprezentacji tekstu, co jest o wiele bardziej skomplikowane, niż wielu programistów zdaje sobie sprawę.