Python UTF-8 comparaison
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
Ce qui se passe là-dedans?
edit= je suis désolé, c'était mon erreur. C'est encore Faux. Je suis à l'aide de Python 2.6 sur Ubuntu 10.04.
- Pourquoi avez-vous vous attendez à ce que la comparaison entre une chaîne et un dict donnerait n'importe quoi mais
False
? Qu'attendiez-vous?
Vous devez vous connecter pour publier un commentaire.
Solutions possibles
Écrire comme ceci:
Ou comme ceci (vous pouvez également ignorer les
.decode('utf-8')
sur les deux côtés):Ou comme ceci (ma recommandation):
Explication
Mis à jour en fonction de Tim commentaire. Dans votre code,
b.decode('utf-8') == u'çö'
eta['a'] == 'çö'
, de sorte que vous êtes en train de faire la comparaison suivante:L'un des objets est de type
unicode
, l'autre est de typestr
, de sorte que, pour l'exécution de la comparaison, lestr
est converti àunicode
et puis les deuxunicode
objets sont comparés. Il fonctionne très bien dans le cas de purement chaînes ASCII, par exemple:u'a' == 'a'
, depuisunicode('a') == u'a'
.Cependant, il échoue dans le cas de
u'çö' == 'çö'
, depuisunicode('çö')
renvoie l'erreur suivante: UnicodeDecodeError: 'ascii' codec ne peut pas décoder les octets 0xc3 en position 0: ordinal pas in range(128), et donc l'ensemble de comparaison renvoie False et les enjeux de l'avertissement suivant: UnicodeWarning: Unicode comparaison égale a échoué à convertir à la fois les arguments en Unicode - interpréter comme étant inégale.b
est unstring
,a
est undict
Vous voulez (je crois):
b == a['a']
UTF-8 est un encodage utilisé pour enregistrer le texte Unicode dans les fichiers. Toutefois, en Python vous travaillez avec des objets qui ont un moyen de représenter le texte Unicode, et de cette façon n'est pas de l'UTF-8.
Vous pouvez toujours comparer des chaînes Unicode Python, mais c'est sans rapport avec l'UTF-8, sauf que si vous voulez mettre des constantes dans ces chaînes Unicode, alors vous aurez besoin d'encoder le texte du fichier contenant votre code source, en UTF-8. Dès que l'opérateur d'affectation est exécutée, la chaîne n'est plus UTF-8, mais c'est maintenant le Python représentation interne.
Par ailleurs, si vous faites des comparaisons avec Unicode, vous souhaiterez probablement utiliser le unicodedata module et de normaliser les cordes avant de comparaisons sont faites.
Essayer
b == a['un']
De la comparaison d'une chaîne à une dict.
Si vous comparez la chaîne (b) le membre de (a['a']), puis vous obtenez le résultat souhaité.
Assurez-vous que votre code est en UTF-8 (et NON en Latin-1) et/ou d'utiliser une ligne de codage de la manière suivante:
Si vous êtes en utilisant unicode, vous pouvez importer unicode_literals de l'avenir et de réduire l'encodage des chagrins d'amour:
Si un fichier utilise unicode_literals, toutes les "ficelles" sont maintenant u"unicode" des objets (par le codage du fichier) s'ils ne sont pas b"ajouté" avec un b (pour émuler la chaîne/octets divisé en Python 3.X).
NullUserException est juste que cela doit être correct:
Vous êtes encore en train de "Faux" parce que vous êtes le décodage d'un côté comme de l'utf-8 (création d'une chaîne Unicode) tandis que l'autre reste une codé en utf-8 chaîne d'octets.