as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!
Comment le réparer?
Dans certaines autres applications de blog statiques basées sur python, la publication en chinois peut être publiée avec succès . Comme cette application: http://github.com/vrypan/bucket3 . Sur mon site http://bc3.brite.biz/ , la publication en chinois peut être publiée avec succès.
Je l'ai finalement eu:
as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Laisse moi vérifier:
as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec 6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>
Ce qui précède montre que l'encodage par défaut de python est utf8
. Alors l'erreur n'est plus.
sys.setdefaultencoding('utf8')
)C'est un méchant hack (il y a une raison pour laquelle vous devez utiliser reload
) qui ne fait que masquer les problèmes et gêner votre migration vers Python 3.x. Comprenez le problème, corrigez la cause première et profitez de zen Unicode ... Voir Pourquoi ne devrions-nous pas utiliser sys.setdefaultencoding ("utf-8") dans un script py? pour plus de détails
Sans voir la source, il est difficile de connaître la cause du problème, il faudra donc que je parle de manière générale.
UnicodeDecodeError: 'ascii' codec can't decode byte
se produit généralement lorsque vous essayez de convertir une str
Python 2.x contenant des chaînes non-ASCII en chaîne Unicode sans spécifier le codage de la chaîne d'origine.
En bref, les chaînes Unicode sont un type de chaîne Python entièrement séparé qui ne contient aucun encodage. Ils ne contiennent que des codes Unicode point et peuvent donc contenir n'importe quel point Unicode de tout le spectre. Les chaînes contiennent du texte codé, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5, etc. Les chaînes sont décodées en Unicode et Unicodes sont codés en chaînes. Les fichiers et les données de texte sont toujours transférés dans des chaînes codées.
Les auteurs du module Markdown utilisent probablement unicode()
(où l'exception est levée) comme porte de qualité vers le reste du code. Il convertit ASCII ou ré-encapsule les chaînes Unicodes existantes dans une nouvelle chaîne Unicode. Les auteurs de Markdown ne peuvent pas connaître l'encodage de la chaîne entrante et vous demanderont donc de décoder des chaînes en chaînes Unicode avant de les transmettre à Markdown.
Les chaînes Unicode peuvent être déclarées dans votre code à l'aide du préfixe u
des chaînes. Par exemple.
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
Les chaînes Unicode peuvent également provenir de fichiers, de bases de données et de modules réseau. Lorsque cela se produit, vous n'avez pas à vous soucier de l'encodage.
La conversion de str
en Unicode peut avoir lieu même si vous n'appelez pas explicitement unicode()
.
Les scénarios suivants entraînent des exceptions UnicodeDecodeError
:
# Explicit conversion without encoding
unicode('€')
# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')
# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'
# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'
Dans le diagramme suivant, vous pouvez voir comment Word café
a été codé au format "UTF-8" ou "Cp1252" en fonction du type de terminal. Dans les deux exemples, caf
est simplement un ascii régulier. En UTF-8, é
est codé sur deux octets. Dans "Cp1252", é est 0xE9 (ce qui est également la valeur du point Unicode (ce n'est pas une coïncidence)). Le nom_fonction __ correct est appelé et la conversion en un code Unicode Python est réussie:
Dans ce diagramme, decode()
est appelé avec ascii
(ce qui revient à appeler decode()
sans codage fourni). Comme ASCII ne peut pas contenir plus d'octets que 0x7F
, une exception UnicodeDecodeError
sera émise:
C'est une bonne pratique de former un sandwich Unicode dans votre code, où vous décodez toutes les données entrantes en chaînes Unicode, travaillez avec Unicodes, puis encodez en str
s à la sortie. Cela vous évite de vous soucier de l'encodage des chaînes au milieu de votre code.
Si vous devez intégrer du code non-ASCII dans votre code source, créez simplement des chaînes Unicode en préfixant celle-ci avec un u
. Par exemple.
u'Zürich'
Pour permettre à Python de décoder votre code source, vous devrez ajouter un en-tête de codage correspondant au codage réel de votre fichier. Par exemple, si votre fichier a été codé en tant que 'UTF-8', vous utiliserez:
# encoding: utf-8
Cela n’est nécessaire que si vous avez non-ASCII dans votre code source .
Habituellement, les données non-ASCII sont reçues d'un fichier. Le module io
fournit un TextWrapper qui décode votre fichier à la volée, en utilisant une encoding
donnée. Vous devez utiliser le bon encodage pour le fichier - il est difficile à deviner. Par exemple, pour un fichier UTF-8:
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
my_unicode_string = my_file.read()
my_unicode_string
conviendrait alors pour passer à Markdown. Si une UnicodeDecodeError
de la ligne unicode()
, vous avez probablement utilisé une valeur de codage incorrecte.
Le module CSV Python 2.7 ne prend pas en charge les caractères non-ASCII ????. De l’aide est cependant disponible avec https://pypi.python.org/pypi/backports.csv .
Utilisez-le comme ci-dessus mais passez le fichier ouvert à celui-ci:
from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
for row in csv.reader(my_file):
yield row
La plupart des pilotes de base de données Python peuvent renvoyer des données au format Unicode, mais nécessitent généralement une petite configuration. Utilisez toujours des chaînes Unicode pour les requêtes SQL.
Dans la chaîne de connexion, ajoutez:
charset='utf8',
use_unicode=True
Par exemple.
>>> db = MySQLdb.connect(Host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
Ajouter:
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
Les pages Web peuvent être encodées dans n'importe quel encodage. L'en-tête Content-type
doit contenir un champ charset
pour indiquer le codage. Le contenu peut ensuite être décodé manuellement contre cette valeur. Alternativement, Python-Requests retourne les Unicodes dans response.text
.Manuellement.
read()
, où encoding
est le codage approprié. Les codecs supportés par Python 2.x sont donnés ici: Encodages standard . Encore une fois, si vous obtenez UnicodeDecodeError
, alors vous aurez probablement le mauvais encodage.La viande du sandwich.
Sortie.
print
écrit dans le flux stdout. Python essaie de configurer un encodeur sur stdout afin que les Unicodes soient encodés dans l'encodage de la console. Par exemple, si la variable locale
du shell Linux est en_GB.UTF-8
, la sortie sera codée en UTF-8
. Sous Windows, vous serez limité à une page de code 8 bits.Une console configurée de manière incorrecte, telle que des paramètres régionaux corrompus, peut entraîner des erreurs d'impression inattendues. La variable d'environnement PYTHONIOENCODING
peut forcer le codage pour stdout.
Des dossiers
io.open
peut être utilisé pour convertir de manière transparente des Unicodes en chaînes d'octets codées.Base de données.
Python 3.
str
est maintenant une chaîne Unicode et l'ancienne str
est maintenant bytes
.Le codage par défaut est maintenant UTF-8. Par conséquent, si vous _my_string.decode(encoding)
une chaîne d'octets sans indiquer de codage, Python 3 utilise le codage UTF-8. Cela corrige probablement 50% des problèmes Unicode des personnes.
De plus, .decode()
fonctionne en mode texte par défaut et renvoie donc __diffusé __ décodé __ (Unicode). Le codage est dérivé de vos paramètres régionaux, qui ont tendance à être UTF-8 sur les systèmes Un * x ou une page de code 8 bits, telle que Windows-1251, sur des fenêtres Windows.
Further, open()
operates in text mode by default, so returns decoded str
(Unicode ones). The encoding is derived from your locale, which tends to be UTF-8 on Un*x systems or an 8-bit code page, such as windows-1251, on Windows boxes.
C’est le classique "problème unicode". Je pense qu'expliquer cela dépasse le cadre d'une réponse StackOverflow pour expliquer complètement ce qui se passe.
C'est bien expliqué ici .
En résumé, vous avez passé quelque chose qui est interprété comme une chaîne d'octets à quelque chose qui doit le décoder en caractères Unicode, mais le codec par défaut (ascii) échoue.
La présentation que je vous ai indiquée fournit des conseils pour éviter cela. Faites de votre code un "sandwich unicode". En Python 2, l'utilisation de "from __future__ import unicode_literals" aide.
Mise à jour: comment corriger le code:
OK - dans votre variable "source", vous avez quelques octets. Votre question ne dit pas clairement comment ils y sont entrés - peut-être les lisez-vous à partir d’un formulaire Web? Dans tous les cas, ils ne sont pas encodés avec ascii, mais python tente de les convertir en unicode en supposant qu'ils le soient. Vous devez lui indiquer explicitement ce qu'est l'encodage. Cela signifie que vous devez savoir ce qu'est l'encodage! Ce n’est pas toujours facile et tout dépend de la provenance de cette chaîne. Vous pouvez expérimenter avec certains codages courants, par exemple UTF-8. Vous indiquez le codage à unicode () comme second paramètre:
source = unicode(source, 'utf-8')
Dans certains cas, lorsque vous vérifiez votre codage par défaut (print sys.getdefaultencoding()
), il indique que vous utilisez ASCII. Si vous changez pour UTF-8, cela ne fonctionnera pas, cela dépend du contenu de votre variable .
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')
"UnicodeDecodeError: 'ascii' codec can't decode byte"
Cause de cette erreur: chaîne_entrée doit être unicode mais str a été donné
"TypeError: Decoding Unicode is not supported"
Cause de cette erreur: tentative de convertir unicode input_string en unicode
Donc, vérifiez d’abord que votre chaîne input_string est str
et convertissez-le en unicode si nécessaire:
if isinstance(input_string, str):
input_string = unicode(input_string, 'utf-8')
Deuxièmement, ce qui précède modifie simplement le type mais ne supprime pas les caractères non ascii. Si vous souhaitez supprimer des caractères non-ASCII:
if isinstance(input_string, str):
input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.
Elif isinstance(input_string, unicode):
input_string = input_string.encode('ascii', 'ignore')
Je cherchais à résoudre le message d'erreur suivant:
unicodedecodeerror: le codec 'ascii' ne peut pas décoder l'octet 0xe2 en position 5454: l'ordinal n'est pas dans la plage (128)
Je l'ai finalement résolu en spécifiant 'encoding':
f = open('../glove/glove.6B.100d.txt', encoding="utf-8")
Je souhaite que cela puisse vous aider aussi.
Je trouve que le mieux est de toujours convertir en unicode, mais c'est difficile à réaliser, car dans la pratique, il faudrait vérifier et convertir tous les arguments en fonctions et méthodes que vous avez écrites, y compris une forme de traitement de chaîne.
J'ai donc proposé l'approche suivante pour garantir des chaînes de caractères unicodes ou octets, quelle que soit l'entrée. En bref, inclut et utilise les lambdas suivants:
# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: Tuple(_u(t) for t in tt)
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: Tuple(_u8(t) for t in tt)
Exemples:
text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))
Voici un peu plus raisonnement à ce sujet .
Encode convertit un objet unicode en un objet chaîne. Je pense que vous essayez d'encoder un objet string. convertissez d'abord votre résultat en objet unicode, puis encodez-le en 'utf-8' ..__
result = yourFunction()
result.decode().encode('utf-8')
J'ai eu le même problème mais cela n'a pas fonctionné pour Python 3. Je l'ai suivi et cela a résolu mon problème:
enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)
Vous devez définir le codage lorsque vous lisez/écrivez le fichier.
En bref, pour assurer une gestion correcte de l’unicode dans Python 2:
io.open
pour lire/écrire des fichiersfrom __future__ import unicode_literals
print(text.encode('ascii', 'replace').decode())
Pour des explications, voir @Alastair McCormack réponse détaillée .
J'ai eu le même problème avec la chaîne "Pastelería Mallorca" et j'ai résolu avec:
unicode("PastelerÃa Mallorca", 'latin-1')
Cette erreur se produit lorsque notre chaîne contient des caractères autres que des caractères ASCII et que nous effectuons des opérations sur cette chaîne sans décodage correct . colonnes ID, texte et décodage des caractères comme ci-dessous:
train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
print("ID :" + i[0])
text = i[1].decode("utf-8",errors="ignore").strip().lower()
print("Text: " + text)
Dans un projet Django (1.9.10)/Python 2.7.5, j'ai des exceptions UnicodeDecodeError
fréquentes; principalement lorsque j'essaie d'alimenter des chaînes de caractères unicode. J'ai créé une fonction d'assistance pour les objets arbitraires afin de formater les chaînes ascii 8 bits et de remplacer tous les caractères qui ne figurent pas dans la table par "?". Je pense que ce n'est pas la meilleure solution, mais puisque l'encodage par défaut est ascii (et je ne veux pas le changer), il conviendra:
def encode_for_logging (c, encoding = 'ascii'): si estinstance (c, basestring): retourne c.encode (encodage, 'remplacer') Elif isinstance (c, Iterable): c_ = [] pour v dans c: c_.append (encode_for_logging (v, encodage)) retourne c _ autre: renvoyer encode_for_logging (unicode (c))`
J'ai eu la même erreur, avec des URL contenant des caractères non-ASCII (octets avec des valeurs> 128)
url = url.decode('utf8').encode('utf-8')
Remarque: utf-8, utf8 sont simplement des alias. Utiliser uniquement 'utf8' ou 'utf-8' devrait fonctionner de la même manière
Dans mon cas, travaillant pour moi, en Python 2.7, je suppose que cette assignation a changé 'quelque chose' dans la représentation interne str
- c’est-à-dire qu’elle force le décodage correct de la séquence d’octets sauvegardée dans url
et place finalement la chaîne dans un utf-8 str
avec toute la magie au bon endroit . Unicode en Python est une magie noire pour moi . J'espère utile
Vous avez une même erreur et cela a résolu mon erreur. Merci! Python 2 et Python 3 ayant une gestion unicode différente, les fichiers picklés sont tout à fait incompatibles à charger. Utilisez donc l’argument d’encodage de Python Pickle. Le lien ci-dessous m'a aidé à résoudre le problème similaire lorsque j'essayais d'ouvrir des données picklées à partir de mon python 3.7, alors que mon fichier était enregistré à l'origine dans la version 2.x de python. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Je copie la fonction load_pickle dans mon script et appelle le load_pickle (pickle_file ) en chargeant mon input_data comme ceci:
input_data = load_pickle("my_dataset.pkl")
La fonction load_pickle est ici:
def load_pickle(pickle_file):
try:
with open(pickle_file, 'rb') as f:
pickle_data = pickle.load(f)
except UnicodeDecodeError as e:
with open(pickle_file, 'rb') as f:
pickle_data = pickle.load(f, encoding='latin1')
except Exception as e:
print('Unable to load data ', pickle_file, ':', e)
raise
return pickle_data
Cela a fonctionné pour moi:
file = open('docs/my_messy_doc.pdf', 'rb')
Spécifiez: # encoding = utf-8 en haut de votre fichier Python, cela devrait résoudre le problème.
Afin de résoudre ce problème au niveau du système d'exploitation dans une installation Ubuntu, vérifiez les points suivants:
$ locale charmap
Si vous obtenez
locale: Cannot set LC_CTYPE to default locale: No such file or directory
au lieu de
UTF-8
puis définissez LC_CTYPE
et LC_ALL
comme ceci:
$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"