2011-09-21 4 views
7

CPython stocke les chaînes unicode en tant qu'utf-16 ou utf-32 en interne en fonction des options de compilation. Dans utf-16, les générations de découpage de chaînes Python, d'itération et de len semblent fonctionner sur des unités de code, et non sur des points de code, de sorte que les caractères multi-octets se comportent étrangement.Que signifie sys.maxunicode?

Par ex, sur CPython 2.6 avec sys.maxunicode = 65535:

>>> char = u'\U0001D49E' 
>>> len(char) 
2 
>>> char[0:1] 
u'\uu835' 
>>> char[1:2] 
u'\udc9e' 

Selon la documentation Python, sys.maxunicode est "un entier donnant le plus grand point de code pris en charge par un caractère Unicode." Cela signifie-t-il que unicode opérations ne sont pas garantis pour travailler sur des points de code au-delà de sys.maxunicode? Si je veux travailler avec des caractères en dehors du BMP, je dois soit utiliser une construction utf-32 ou écrire mes propres opérations portatives unicode?

je suis tombé sur ce problème dans How to iterate over Unicode characters in Python 3?

+0

Intéressant. Sur CPython 3.2.2 (Win x64), 'sys.maxunicode' est' 65535' ... –

Répondre

3

caractères au-delà sys.maxunicode=65535 sont stockées en interne en utilisant UTF-16 mères porteuses. Oui, vous devez vous occuper de cela vous-même ou utiliser une construction large. Même avec une construction large, vous devrez peut-être gérer des caractères uniques représentés par une combinaison de points de code. Par exemple:

>>> print('a\u0301') 
á 
>>> print('\xe1') 
á 

La première utilise un caractère d'accent combinant et la seconde ne l'utilise pas. Les deux impriment la même chose. Vous pouvez utiliser unicodedata.normalize pour convertir les formulaires.