Je suis vraiment confus. J'ai essayé d'encoder mais l'erreur a dit can't decode...
.
>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
Je sais comment éviter l'erreur avec le préfixe "u" sur la chaîne. Je me demande simplement pourquoi l'erreur est "impossible de décoder" lorsque l'encode a été appelé. Que fait Python sous le capot?
"你好".decode('utf-8').encode('utf-8')
Encodez toujours de Unicode en octets.
Dans cette direction, vous choisissez l'encodage .
L'autre façon consiste à décoder des octets en unicode.
Dans ce sens, vous devez savoir quel est le codage .
Ce point ne peut pas être assez souligné. Si vous voulez éviter de jouer unicode "whack-a-mole", il est important de comprendre ce qui se passe au niveau des données. Ici, il est expliqué d'une autre manière:
decode
.encode
.Maintenant, en voyant
.encode
une chaîne d'octets, Python 2 essaie d'abord de la convertir implicitement en texte (ununicode
objet). De même, en voyant.decode
sur une chaîne unicode, Python 2 essaie implicitement de la convertir en octets (unstr
objet).Ces conversions implicites sont la raison pour laquelle vous pouvez obtenir lorsque vous avez appelé . C'est parce que l'encodage accepte généralement un paramètre de type ; lors de la réception d'un paramètre, il y a un décodage implicite dans un objet de type avant de le recoder avec un autre encodage. Cette conversion choisit un décodeur «ascii» par défaut † , vous donnant l'erreur de décodage à l'intérieur d'un encodeur.
Unicode
Decode
Error
encode
unicode
str
unicode
En fait, en Python 3 , les méthodes
str.decode
etbytes.encode
n'existent même pas. Leur suppression était une tentative [controversée] d'éviter cette confusion courante.† ... ou tout ce que le codage
sys.getdefaultencoding()
mentionne; il s'agit généralement de 'ascii'la source
_
fait référence à la valeur précédente 2. car c'est une question python-2.x.Vous pouvez essayer ceci
Ou
Vous pouvez également essayer de suivre
Ajoutez la ligne suivante en haut de votre fichier .py.
la source
Si vous utilisez Python <3, vous devrez dire à l'interpréteur que votre chaîne littérale est Unicode en la préfixant avec un
u
:Lectures complémentaires : HOWTO Unicode .
la source
Vous utilisez
u"你好".encode('utf8')
pour encoder une chaîne unicode. Mais si vous voulez représenter"你好"
, vous devez le décoder. Juste comme:Vous obtiendrez ce que vous voulez. Vous devriez peut-être en savoir plus sur l'encodage et le décodage.
la source
Dans le cas où vous avez affaire à Unicode, parfois au lieu de
encode('utf-8')
, vous pouvez également essayer d'ignorer les caractères spéciaux, par exempleou comme
something.decode('unicode_escape').encode('ascii','ignore')
suggéré ici .Pas particulièrement utile dans cet exemple, mais peut mieux fonctionner dans d'autres scénarios lorsqu'il n'est pas possible de convertir certains caractères spéciaux.
Vous pouvez également envisager de remplacer un caractère particulier en utilisant
replace()
.la source
Si vous démarrez l'interpréteur python à partir d'un shell sur Linux ou des systèmes similaires (BSD, pas sûr pour Mac), vous devez également vérifier l'encodage par défaut pour le shell.
Appelez
locale charmap
depuis le shell (pas l'interpréteur python) et vous devriez voirSi ce n'est pas le cas et que vous voyez autre chose, par exemple
Python héritera (au moins dans certains cas comme dans le mien) du codage du shell et ne pourra pas imprimer (certains? Tous?) Les caractères Unicode. L'encodage par défaut de Python que vous voyez et contrôlez via
sys.getdefaultencoding()
etsys.setdefaultencoding()
est dans ce cas ignoré.Si vous constatez que vous rencontrez ce problème, vous pouvez le résoudre en
(Ou bien choisissez le keymap que vous voulez au lieu de en_EN.) Vous pouvez également éditer
/etc/locale.conf
(ou le fichier qui régit la définition des paramètres régionaux dans votre système) pour corriger cela.la source