Python UTF-8 confronto
-
25-09-2019 - |
Domanda
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
Che cosa sta succedendo là dentro?
modifica = Mi dispiace, è stato un mio errore. E 'ancora False. Sto usando Python 2.6 su Ubuntu 10.04.
Soluzione
Possibili soluzioni
In ogni scrittura in questo modo:
a = {"a": u"çö"}
b = "çö"
b.decode('utf-8') == a['a']
O come questo (si può anche saltare la .decode('utf-8')
su entrambi i lati):
a = {"a": "çö"}
b = "çö"
b.decode('utf-8') == a['a'].decode('utf-8')
O come questo (la mia raccomandazione):
a = {"a": u"çö"}
b = u"çö"
b == a['a']
Spiegazione
aggiornato in base al commento di Tim Nel codice originale, b.decode('utf-8') == u'çö'
e a['a'] == 'çö'
, così si sta effettivamente facendo il seguente confronto:.
u'çö' == 'çö'
Uno degli scopi è di tipo unicode
, l'altro è di tipo str
, quindi per eseguire il confronto, la str
viene convertito unicode
e poi i due oggetti unicode
vengono confrontati. Funziona bene nel caso di puramente stringhe ASCII, ad esempio:. u'a' == 'a'
, dal momento che unicode('a') == u'a'
Tuttavia, non riesce in caso di u'çö' == 'çö'
, poiché restituisce unicode('çö')
il seguente errore: UnicodeDecodeError: 'ascii' codec non può decodificare byte 0xc3 in posizione 0: senza ordinale nella gamma (128) , e quindi tutto il confronto restituisce false e problemi il seguente avviso: UnicodeWarning: Unicode uguale confronto non è riuscito a convertire entrambi gli argomenti a Unicode - interpretandoli come disuguale
Altri suggerimenti
b
è un string
, a
è un dict
Si vuole (credo):
b == a['a']
UTF-8 è una codifica utilizzata per registrare il testo Unicode nei file. Tuttavia, in Python si sta lavorando con gli oggetti che hanno un modo fisso per rappresentare il testo Unicode, e in questo modo non è UTF-8.
È ancora possibile confrontare le stringhe Unicode in Python, ma questo non è correlato a UTF-8, salvo che, se si vuole mettere le costanti in queste stringhe Unicode, allora si avrà bisogno per codificare il testo del file che contiene il codice sorgente, in UTF-8. Non appena viene eseguita l'operatore di assegnazione, la stringa è più UTF-8, ma ora è la rappresentazione interna Python.
A proposito, se si sta facendo paragoni con Unicode, probabilmente vorrà utilizzare il modulo unicodedata e normalizzare le stringhe prima di comparazioni sono fatte.
Prova b == un [ 'a']
si sta confrontando una stringa in un dict.
>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True
Se si confronta la stringa (b) al membro di una (un [ 'a']), allora si ottiene il risultato desiderato.
Assicurati che il tuo codice è in UTF-8 (non Latin-1) e / o utilizzare una linea di codifica come:
#! /usr/bin/python
# -*- coding: utf-8 -*-
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b.decode('utf-8') == a['a'].decode('utf-8')
Se si utilizza unicode su tutta la linea, è possibile importare unicode_literals dal futuro e tagliare di nuovo sulla codifica angosce:
#! /usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b == a['a']
assert b.encode('utf-8') != a['a']
assert b.encode('utf-8') == a['a'].encode('utf-8')
Se un utilizza il file unicode_literals, tutte le "stringhe" sono ora u oggetti "Unicode" (per la codifica del file) se non sono b "anteporre" con ab (per emulare la stringa / byte diviso in Python 3 .X).
NullUserException è giusto che questo dovrebbe essere corretto:
b == a['a']
Si sta ancora ricevendo "False" perché si sta decodificando un lato come utf-8 (la creazione di una stringa Unicode) mentre l'altro lato rimane una stringa di byte codificati UTF-8.