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 chinoise peut être publiée avec succès. Tels que cette application: http://github.com/vrypan/bucket3 . Sur mon site http://bc3.brite.biz/ , la publication chinoise peut être publiée avec succès.
python
python-2.7
chinese-locale
pêcheur
la source
la source
Réponses:
tl; dr / quick fix
reload
hacks rapidesUnicode Zen dans Python 2.x - La version longue
Sans voir la source, il est difficile de connaître la cause profonde, je vais donc devoir parler de manière générale.
UnicodeDecodeError: 'ascii' codec can't decode byte
se produit généralement lorsque vous essayez de convertir un Python 2.xstr
qui contient non-ASCII en une 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 distinct qui ne contient aucun encodage. Ils ne contiennent que des codes de point Unicode et peuvent donc contenir n'importe quel point Unicode de l'ensemble du 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 les Unicodes sont codés en chaînes . Les fichiers et les données texte sont toujours transférés dans des chaînes codées.
Les auteurs du module Markdown utilisent probablement
unicode()
(là où l'exception est levée) comme une porte de qualité vers le reste du code - il convertira ASCII ou ré-emballera les chaînes Unicodes existantes en une nouvelle chaîne Unicode. Les auteurs de Markdown ne peuvent pas connaître l'encodage de la chaîne entrante, ils comptent donc sur vous pour décoder les chaînes en chaînes Unicode avant de passer à Markdown.Les chaînes Unicode peuvent être déclarées dans votre code en utilisant le
u
préfixe des chaînes. Par exempleLes 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.
Gotchas
La conversion de
str
à Unicode peut se produire même lorsque vous n'appelez pas explicitementunicode()
.Les scénarios suivants provoquent des
UnicodeDecodeError
exceptions:Exemples
Dans le diagramme suivant, vous pouvez voir comment le mot
café
a été encodé en encodage "UTF-8" ou "Cp1252" en fonction du type de terminal. Dans les deux exemples,caf
c'est juste un ascii régulier. En UTF-8,é
est codé en utilisant deux octets. Dans "Cp1252", é est 0xE9 (qui est également la valeur du point Unicode (ce n'est pas un hasard)). Le correctdecode()
est invoqué et la conversion en Unicode Python est réussie:Dans ce diagramme,
decode()
est appelé avecascii
(ce qui revient à appelerunicode()
sans codage donné). Comme ASCII ne peut pas contenir d'octets supérieurs à0x7F
, cela lèvera uneUnicodeDecodeError
exception:Le sandwich Unicode
Il est recommandé 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 du codage des chaînes au milieu de votre code.Entrée / décodage
Code source
Si vous avez besoin de créer des chaînes non ASCII dans votre code source, créez simplement des chaînes Unicode en préfixant la chaîne avec un
u
. Par exemplePour permettre à Python de décoder votre code source, vous devrez ajouter un en-tête de codage pour correspondre au codage réel de votre fichier. Par exemple, si votre fichier a été encodé en 'UTF-8', vous utiliseriez:
Cela n'est nécessaire que si vous avez un code non ASCII dans votre code source .
Des dossiers
Habituellement, les données non ASCII sont reçues d'un fichier. Le
io
module fournit un TextWrapper qui décode votre fichier à la volée, en utilisant une donnéeencoding
. Vous devez utiliser l'encodage correct pour le fichier - il ne peut pas être facilement deviné. Par exemple, pour un fichier UTF-8:my_unicode_string
serait alors adapté pour passer à Markdown. Si unUnicodeDecodeError
de laread()
ligne, alors vous avez probablement utilisé la mauvaise valeur de codage.Fichiers CSV
Le module Python 2.7 CSV ne prend pas en charge les caractères non ASCII 😩. Cependant, l'aide est à portée de main avec https://pypi.python.org/pypi/backports.csv .
Utilisez-le comme ci-dessus mais passez-lui le fichier ouvert:
Bases de données
La plupart des pilotes de base de données Python peuvent renvoyer des données en Unicode, mais nécessitent généralement un peu de configuration. Utilisez toujours des chaînes Unicode pour les requêtes SQL.
MySQLDans la chaîne de connexion, ajoutez:
Par exemple
PostgreSQLAjouter:
HTTP
Les pages Web peuvent être encodées dans à peu près n'importe quel encodage. L'en-
Content-type
tête doit contenir uncharset
champ pour indiquer l'encodage. Le contenu peut ensuite être décodé manuellement par rapport à cette valeur. Alternativement, Python-Requests renvoie Unicodes dansresponse.text
.Manuellement
Si vous devez décoder les chaînes manuellement, vous pouvez simplement le faire
my_string.decode(encoding)
, oùencoding
est l'encodage approprié. Les codecs pris en charge par Python 2.x sont indiqués ici: Codages standard . Encore une fois, si vous obtenez,UnicodeDecodeError
vous avez probablement un mauvais codage.La viande du sandwich
Travaillez avec Unicodes comme vous le feriez avec des chaînes normales.
Production
sortie standard / impression
print
écrit via le flux stdout. Python essaie de configurer un encodeur sur stdout afin que les Unicodes soient encodés selon l'encodage de la console. Par exemple, si un shell Linux l'locale
esten_GB.UTF-8
, la sortie sera encodée enUTF-8
. Sous Windows, vous serez limité à une page de codes 8 bits.Une console mal configurée, comme des paramètres régionaux corrompus, peut entraîner des erreurs d'impression inattendues.
PYTHONIOENCODING
La variable d'environnement peut forcer l'encodage pour stdout.Des dossiers
Tout comme l'entrée,
io.open
peut être utilisé pour convertir de manière transparente des Unicodes en chaînes d'octets codées.Base de données
La même configuration de lecture permettra d'écrire directement les Unicodes.
Python 3
Python 3 n'est pas plus compatible Unicode que Python 2.x, mais il est légèrement moins confus sur le sujet. Par exemple, le régulier
str
est maintenant une chaîne Unicode et l'ancien l'str
est maintenantbytes
.L'encodage par défaut est UTF-8, donc si vous
.decode()
une chaîne d'octets sans donner d'encodage, Python 3 utilise l'encodage UTF-8. Cela résout probablement 50% des problèmes Unicode des utilisateurs.De plus,
open()
fonctionne en mode texte par défaut, donc retourne décodéstr
(ceux Unicode). L'encodage est dérivé de votre environnement local, qui a tendance à être UTF-8 sur les systèmes Un * x ou une page de code 8 bits, telle que windows-1251, sur les boîtes Windows.Pourquoi vous ne devriez pas utiliser
sys.setdefaultencoding('utf8')
C'est un hack méchant (il y a une raison que vous devez utiliser
reload
) qui ne fera 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 d'Unicode zen. Voir Pourquoi ne devrions-nous PAS utiliser sys.setdefaultencoding ("utf-8") dans un script py? pour plus de détailsla source
io.open
pour lire / écrire des fichiers, utilisezfrom __future__ import unicode_literals
, configurez d'autres entrées / sorties de données (par exemple, des bases de données) pour utiliser unicode.PYTHONIOENCODING=utf-8
. Si cela ne le résout pas, vous devrez contacter l'auteur du script pour corriger leur code.Je l'ai finalement eu:
Laisse moi vérifier:
Ce qui précède montre l'encodage par défaut de python
utf8
. Alors l'erreur n'est plus.la source
str
, donc ce n'est pas en retard. Dans Python 2.x, Unicode était dans un état de transition, il aurait donc été dangereux de supposer un encodage lors de la conversion d'octets en Unicodes. Par conséquent, le codage par défaut de Py2 en ASCII était un choix délibéré et pourquoi changer le codage par défaut nécessite le piratage délibéré du rechargementsys
. La bonne façon de bannir les erreurs de codage dans Py2 est de décoder et de coder sans ambiguïté les chaînes (octets) en Unicode, lorsque des conversions sont nécessaires - et pas seulement de supposer que les chaînes sont codées en UTF-8.Il s'agit du «problème unicode» classique. Je pense qu'expliquer cela dépasse la portée d'une réponse StackOverflow pour expliquer complètement ce qui se passe.
C'est bien expliqué ici .
En résumé très bref, vous avez transmis 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 d'
from __future__ import unicode_literals
aides.Mise à jour: comment réparer le code:
OK - dans votre variable "source", vous avez quelques octets. Il n'est pas clair à partir de votre question comment ils y sont entrés - peut-être les avez-vous lus à partir d'un formulaire Web? Dans tous les cas, ils ne sont pas encodés avec ascii, mais python essaie de les convertir en unicode en supposant qu'ils le sont. Vous devez lui dire explicitement quel est le codage. Cela signifie que vous devez savoir quel est l'encodage! Ce n'est pas toujours facile et cela dépend entièrement de l'origine de cette chaîne. Vous pouvez expérimenter avec certains encodages courants - par exemple UTF-8. Vous indiquez à unicode () l'encodage comme deuxième paramètre:
la source
currentFile = open(filename, 'rt', encoding='latin1')
oucurrentFile = open(filename, 'rt', encoding='utf-8')
- voir ici: stackoverflow.com/a/23917799/2047442Dans certains cas, lorsque vous vérifiez votre encodage par défaut (
print sys.getdefaultencoding()
), il retourne que vous utilisez ASCII. Si vous passez à UTF-8, cela ne fonctionne pas, selon le contenu de votre variable. J'ai trouvé un autre moyen:la source
reload(sys)
est utilisé pour cette raison particulière.Je cherchais à résoudre le message d'erreur suivant:
Je l'ai finalement corrigé en spécifiant 'encodage':
Je souhaite que cela puisse vous aider aussi.
la source
Cause de cette erreur: input_string doit être unicode mais str a été donné
Cause de cette erreur: tentative de conversion d'unicode input_string en unicode
Vérifiez donc d'abord que votre chaîne d'entrée est
str
et convertissez-la en unicode si nécessaire:Deuxièmement, ce qui précède change juste le type mais ne supprime pas les caractères non ascii. Si vous souhaitez supprimer des caractères non ascii:
la source
Je trouve que le mieux est de toujours convertir en unicode - mais cela est difficile à réaliser car dans la pratique, vous devrez vérifier et convertir chaque argument en chaque fonction et méthode que vous écrivez qui inclut une certaine forme de traitement de chaîne.
J'ai donc proposé l'approche suivante pour garantir des unicodes ou des chaînes d'octets, à partir de l'une ou l'autre entrée. En bref, incluez et utilisez les lambdas suivants:
Exemples:
Voici un peu plus de raisonnement à ce sujet .
la source
print unicode(u'Zürich', encoding="UTF-8")
et ensuite se plaindre "Mais étonnamment, vous ne pouvez pas coder ext unicode en UTF8".unicode()
ne code pas; il décode et vous ne pouvez pas décoder un Unicode - il est déjà décodé!Afin de résoudre ce problème au niveau du système d'exploitation dans une installation Ubuntu, vérifiez les points suivants:
Si vous obtenez
au lieu de
puis définissez
LC_CTYPE
etLC_ALL
comme ceci:la source
Encode convertit un objet unicode en un objet chaîne. Je pense que vous essayez d'encoder un objet chaîne. convertissez d'abord votre résultat en objet unicode, puis encodez cet objet unicode en «utf-8». par exemple
la source
J'ai eu le même problème mais cela n'a pas fonctionné pour Python 3. J'ai suivi cela et cela a résolu mon problème:
Vous devez définir l'encodage lorsque vous lisez / écrivez le fichier.
la source
Vous avez une même erreur et cela a résolu mon erreur. Merci! python 2 et python 3 différents dans la gestion unicode rendent les fichiers picklés assez incompatibles à charger. Utilisez donc l'argument de codage de python pickle. Le lien ci-dessous m'a aidé à résoudre le problème similaire lorsque j'essayais d'ouvrir des données marinées à partir de mon python 3.7, alors que mon fichier était initialement enregistré dans la version python 2.x. 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 j'ai appelé load_pickle (pickle_file) lors du chargement de mon input_data comme ceci:
La fonction load_pickle est ici:
la source
load_pickle
fonction dans votre réponse.Cela a fonctionné pour moi:
la source
En bref, pour assurer une bonne gestion 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 la réponse détaillée de @Alastair McCormack .
la source
io.open(path, 'r', encoding='utf-8')
pour lire les fichiers encodés en utf-8.J'ai eu la même erreur, avec des URL contenant des caractères non ascii (octets avec des valeurs> 128), ma solution:
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, a fonctionné pour moi, en Python 2.7, je suppose que cette affectation a changé «quelque chose» dans la
str
représentation interne - c'est-à-dire qu'elle force le bon décodage de la séquence d'octets sauvegardéeurl
et met finalement la chaîne dans un utf-8str
avec toute la magie au bon endroit. Unicode en Python est de la magie noire pour moi. J'espère utilela source
J'ai eu le même problème avec la chaîne "Pastelería Mallorca" et j'ai résolu avec:
la source
Dans un projet Django (1.9.10) / Python 2.7.5 j'ai des
"UnicodeDecodeError
exceptions fréquentes ; principalement lorsque j'essaie d'alimenter les chaînes unicode en journalisation. J'ai créé une fonction d'aide pour les objets arbitraires à formater essentiellement en chaînes ascii 8 bits et en remplaçant tous les caractères absents du tableau par «?». Je pense que ce n'est pas la meilleure solution mais comme l'encodage par défaut est ascii (et je ne veux pas le changer), il fera:la source
Cette erreur se produit lorsqu'il y a des caractères non ASCII dans notre chaîne et que nous effectuons des opérations sur cette chaîne sans décodage approprié. Cela m'a aidé à résoudre mon problème. Je lis un fichier CSV avec l'ID des colonnes, le texte et les caractères de décodage comme ci-dessous:
la source
Voici ma solution, il suffit d'ajouter l'encodage.
with open(file, encoding='utf8') as f
Et parce que la lecture du fichier des gants prendra beaucoup de temps, je recommande le fichier des gants à un fichier numpy. Lorsque le temps netx vous lisez les poids d'intégration, cela vous fera gagner du temps.
Lien essentiel: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
la source
Spécifiez: # encoding = utf-8 en haut de votre fichier Python, cela devrait résoudre le problème
la source