2010-03-10 5 views
4

J'essaie de comprendre comment python 2.5 traite les chaînes Unicode. Bien que je pense avoir une bonne compréhension de la façon dont je suis censé les manipuler dans le code, je ne comprends pas très bien ce qui se passe dans les coulisses, en particulier lorsque vous tapez des chaînes à l'invite de l'interpréteur. Donc python pre 3.0 a deux types pour les chaînes, à savoir: str (chaînes d'octets) et unicode, qui sont tous deux dérivés de basestring. Le type par défaut pour les chaînes est str.Les chaînes Python Unicode et l'interpréteur interactif Python

str Les objets n'ont aucune notion de leur codage réel, ils ne sont que des octets. Soit vous avez encodé vous-même une chaîne Unicode et donc vous savez dans quel encodage ils se trouvent, soit vous avez lu un flux d'octets dont vous connaissez également l'encodage (indeally). Vous pouvez deviner l'encodage d'une chaîne d'octets dont l'encodage vous est inconnu, mais il n'y a tout simplement pas de moyen fiable de le comprendre. Votre meilleur pari est de décoder tôt, d'utiliser unicode partout dans votre code et d'encoder en retard.

C'est bon. Mais les cordes dactylographiées dans l'interprète sont-elles codées pour vous derrière votre dos? Pourvu que ma compréhension des chaînes en Python soit correcte, quelle est la méthode/le paramètre utilisé par python pour prendre cette décision?

La source de ma confusion réside dans les résultats différents que j'obtiens lorsque j'essaie la même chose sur l'installation python de mon système, et sur la console python intégrée de mon éditeur.

# Editor (Sublime Text) 
>>> s = "La caña de España" 
>>> s 
'La ca\xc3\xb1a de Espa\xc3\xb1a' 
>>> s.decode("utf-8") 
u'La ca\xf1a de Espa\xf1a' 
>>> sys.getdefaultencoding() 
'ascii' 

# Windows python interpreter 
>>> s= "La caña de España" 
>>> s 
'La ca\xa4a de Espa\xa4a' 
>>> s.decode("utf-8") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python25\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa4 in position 5: unexpected code byte 
>>> sys.getdefaultencoding() 
'ascii' 

Répondre

7

Permettez-moi d'la réponse de Ignacio: Dans les deux cas, il y a une couche supplémentaire entre Python et vous: dans un cas, il est Sublime Text et dans l'autre il est cmd.exe. La différence de comportement que vous voyez n'est pas due à Python mais aux différents encodages utilisés par Sublime Text (utf-8, comme il semble) et cmd.exe (cp437).

Ainsi, lorsque vous tapez ñ, Sublime Text envoie '\xc3\xb1' à Python, alors que cmd.exe envoie \xa4. [Je suis simplement ici, en omettant les détails qui ne sont pas pertinents à la question.].

Pourtant, Python le sait.De cmd.exe vous aurez probablement quelque chose comme:

>>> import sys 
>>> sys.stdin.encoding 
'cp437' 

alors qu'au sein Sublime Text vous obtenez quelque chose comme

>>> import sys 
>>> sys.stdin.encoding 
'utf-8' 
+1

je reçois 'none' en tout Sublime Text:' imprimer sys.stdin. encoding' tandis que dans le ralenti, j'ai 'UTF-8' fonctionnant sous Mac OS X – andi

3

L'interpréteur utilise le codage natif de votre invite de commande pour l'entrée de texte. Dans votre cas, il est CP437:

>>> print '\xa4'.decode('cp437') 
ñ 
0

Tu deviens confus parce que l'éditeur et l'interprète utilisent différents encodages eux-mêmes. L'interpréteur python utilise votre système par défaut (dans ce cas, cp437), tandis que votre éditeur utilise utf-8.

Remarque, la différence disparaît si vous spécifiez une chaîne de caractères Unicode, comme ceci:

# Windows python interpreter 
>>> s = "La caña de España" 
>>> s 
'La ca\xa4a de Espa\xa4a' 
>>> s = u"La caña de España" 
>>> s 
u'La ca\xf1a de Espa\xf1a' 

La morale de l'histoire? Les encodages sont difficiles. Assurez-vous de connaître l'encodage de vos fichiers sources ou de le lire en toute sécurité en utilisant toujours la version d'échappement des caractères spéciaux.

Questions connexes