web-dev-qa-db-fra.com

Pourquoi déclarer unicode par chaîne en python?

J'apprends toujours python et j'ai un doute:

Dans python 2.6.x, je déclare généralement le codage dans l'en-tête du fichier comme ceci (comme dans PEP 026 )

# -*- coding: utf-8 -*-

Après cela, mes chaînes sont écrites comme d'habitude:

a = "A normal string without declared Unicode"

Mais chaque fois que je vois un code de projet python), l'encodage n'est pas déclaré dans l'en-tête. Il est plutôt déclaré à chaque chaîne comme ceci:

a = u"A string with declared Unicode"

Quelle est la différence? Quel est le but de ceci? Je sais que Python 2.6.x définit ASCII l'encodage par défaut, mais il peut être remplacé par la déclaration d'en-tête, alors quel est l'intérêt de la déclaration par chaîne?

Addendum: On dirait que j'ai mélangé le codage de fichier avec le codage de chaîne. Merci de l'expliquer :)

119
Oscar Carballal

Ce sont deux choses différentes, comme d'autres l'ont mentionné.

Lorsque vous spécifiez # -*- coding: utf-8 -*-, vous indiquez Python le fichier source que vous avez enregistré est utf-8. _. La valeur par défaut for Python 2 est ASCII (pour Python 3 c'est utf-8. _ l'interprète lit les caractères du fichier.

En général, il n’est probablement pas la meilleure idée d’incorporer des caractères unicode élevés dans votre fichier, quel que soit le codage utilisé; vous pouvez utiliser des échappements chaîne unicode, qui fonctionnent dans l'un ou l'autre codage.


Lorsque vous déclarez une chaîne avec un u devant, comme u'This is a string', il indique au compilateur Python que la chaîne est Unicode, pas des octets, l’interpréteur s’en occupe de manière transparente, la différence la plus évidente étant que vous pouvez maintenant incorporer des caractères Unicode dans la chaîne (c’est-à-dire que u'\u2665' est maintenant légal). Vous pouvez utiliser from __future__ import unicode_literals pour en faire la valeur par défaut.

Ceci s'applique uniquement à Python 2; dans Python 3, la valeur par défaut est Unicode et vous devez spécifier un b devant (comme b'These are bytes', pour déclarer une séquence d'octets).

160
Chris B.

Comme d'autres l'ont dit, # coding: spécifie le codage dans lequel le fichier source est enregistré. Voici quelques exemples pour illustrer cela:

n fichier sauvegardé sur le disque en tant que cp437 (mon encodage de console), mais aucun encodage déclaré

b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)

Sortie:

  File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

Sortie du fichier avec # coding: cp437 ajouté:

über '\x81ber'
über u'\xfcber'

Au début, Python ne connaissait pas l'encodage et se plaignait du caractère non-ASCII. Une fois qu'il connaissait l'encodage, la chaîne d'octets obtenait les octets réellement présents sur le disque. Pour la chaîne Unicode , Python read\x81, savait que dans cp437, c’était un ü, et le décodait dans le codepoint Unicode pour ü qui est U + 00FC Lorsque la chaîne d'octets a été imprimée, Python a envoyé la valeur hexadécimale 81 à la console directement. Lorsque la chaîne Unicode a été imprimée, Python a correctement détecté le codage de ma console en tant que cp437 et a traduit Unicode ü en valeur cp437 pour ü.

Voici ce qui se passe avec un fichier déclaré et enregistré en UTF-8:

├╝ber '\xc3\xbcber'
über u'\xfcber'

En UTF-8, ü est codé sous forme d’octets hexadécimaux C3 BC, la chaîne d'octets contient donc ces octets, mais la chaîne Unicode est identique à celle du premier exemple. Python lit les deux octets et le décode correctement. Python affiche la chaîne d'octets de manière incorrecte, car il a envoyé les deux octets UTF-8 représentant ü directement sur ma console cp437.

Ici, le fichier est déclaré cp437, mais enregistré au format UTF-8:

├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'

La chaîne d'octets contient toujours les octets sur le disque (octets hexadécimaux UTF-8 C3 BC), mais les a interprétés comme deux caractères cp437 au lieu d’un seul caractère encodé en UTF-8. Ces deux caractères ont été traduits en points de code Unicode et tout est imprimé de manière incorrecte.

22
Mark Tolonen

Cela ne définit pas le format de la chaîne; il définit le format du fichier. Même avec cet en-tête, "hello" est une chaîne d'octets, pas une chaîne Unicode. Pour le rendre Unicode, vous devrez utiliser u"hello" partout. L'en-tête est juste un indice du format à utiliser pour lire le .py fichier.

10
icktoofay

La définition de l'en-tête consiste à définir le codage du code lui-même, et non les chaînes résultantes au moment de l'exécution.

mettre un caractère non-ASCII comme ۲ dans le script python sans la définition de l'en-tête utf-8 lève un avertissement error

7
ebt