J'apprends toujours python et j'ai un doute:
En python 2.6.x, je déclare généralement le codage dans l'en-tête du fichier comme ceci (comme dans PEP 0263 )
# -*- 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é à l'en-tête. Au lieu de cela, il est déclaré à chaque chaîne comme ceci:
a = u"A string with declared Unicode"
Quelle est la différence? Quel est le but de cela? Je sais que Python 2.6.x définit le codage ASCII par défaut, mais il peut être remplacé par la déclaration d'en-tête, alors à quoi sert la déclaration par chaîne?
Addendum: Il semble que j'ai mélangé l'encodage de fichiers avec l'encodage de chaînes. Merci de l'expliquer :)
# coding: utf8
est assez bon, pas besoin de-*-
# coding: utf-8
.#coding=utf-8
. python.org/dev/peps/pep-0263Réponses:
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éutf-8
. La valeur par défaut pour Python 2 est ASCII (pour Python 3 c'estutf-8
). Cela affecte simplement la façon dont l'interpréteur lit les caractères dans le fichier.En général, ce n'est probablement pas la meilleure idée d'incorporer des caractères Unicode élevés dans votre fichier, quel que soit le codage; vous pouvez utiliser des échappements de chaîne unicode, qui fonctionnent dans les deux encodages.
Lorsque vous déclarez une chaîne avec un
u
devant , commeu'This is a string'
, cela indique au compilateur Python que la chaîne est Unicode, pas des octets. Ceci est géré en grande partie de manière transparente par l'interprète; la différence la plus évidente est que vous pouvez désormais incorporer des caractères unicode dans la chaîne (c'est-à-dire qu'elleu'\u2665'
est désormais légale). Vous pouvez utiliserfrom __future__ import unicode_literals
pour en faire la valeur par défaut.Cela ne s'applique qu'à Python 2; dans Python 3, la valeur par défaut est Unicode, et vous devez spécifier un
b
devant (commeb'These are bytes'
, pour déclarer une séquence d'octets).la source
Comme d'autres l'ont dit,
# coding:
spécifie le codage dans lequel le fichier source est enregistré. Voici quelques exemples pour illustrer cela:Un fichier enregistré sur le disque en tant que cp437 (mon encodage de console), mais aucun encodage déclaré
Production:
Sortie du fichier avec
# coding: cp437
ajouté:Au début, Python ne connaissait pas l'encodage et se plaignait du caractère non ASCII. Une fois qu'elle a connu le codage, la chaîne d'octets a obtenu les octets qui étaient réellement sur le disque. Pour la chaîne Unicode, Python a lu \ x81, savait que dans cp437 c'était un ü , et l'a décodé dans le point de code Unicode pour ü qui est U + 00FC. Lorsque la chaîne d'octets a été imprimée, Python a envoyé la valeur hexadécimale
81
directement à la console. Lorsque la chaîne Unicode a été imprimée, Python a correctement détecté le codage de ma console en tant que cp437 et traduit Unicode ü en valeur cp437 pour ü .Voici ce qui se passe avec un fichier déclaré et enregistré en UTF-8:
En UTF-8, ü est codé en octets hexadécimaux
C3 BC
, la chaîne d'octets contient donc ces octets, mais la chaîne Unicode est identique au premier exemple. Python a lu les deux octets et les a décodés correctement. Python n'a pas imprimé correctement la chaîne d'octets, car il a envoyé les deux octets UTF-8 représentant ü directement à ma console cp437.Ici, le fichier est déclaré cp437, mais enregistré en UTF-8:
La chaîne d'octets contient toujours les octets sur le disque (octets hexadécimaux UTF-8
C3 BC
), mais les interprète 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 ne s'imprime pas correctement.la source
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, il
"hello"
y a une chaîne d'octets, pas une chaîne Unicode. Pour le rendre Unicode, vous allez devoir l'utiliseru"hello"
partout. L'en-tête n'est qu'une indication du format à utiliser lors de la lecture du.py
fichier.la source
La définition d'en-tête consiste à définir le codage du code lui-même, pas 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 d'en-tête utf-8 lancera un avertissement
la source
J'ai fait le module suivant appelé unicoder pour pouvoir faire la transformation sur les variables:
Ensuite, dans votre programme, vous pouvez effectuer les opérations suivantes:
la source