web-dev-qa-db-fra.com

Comment résoudre UnicodeDecodeError dans Python 3.6?

Je suis passé de Python 2.7 à Python 3.6.

J'ai des scripts qui traitent de certains contenus non anglais.

J'exécute généralement des scripts via Cron et également dans Terminal.

J'avais UnicodeDecodeError dans mes scripts Python 2.7 et j'ai résolu cela.

# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Maintenant, dans Python 3.6, cela ne fonctionne pas. J'ai des instructions d'impression comme print("Here %s" % (myvar)) et cela génère une erreur. Je peux résoudre ce problème en le remplaçant par myvar.encode("utf-8") mais je ne veux pas écrire avec chaque instruction d'impression.

J'ai fait PYTHONIOENCODING=utf-8 Dans mon terminal et j'ai toujours ce problème.

Existe-t-il un moyen plus propre de résoudre le problème de UnicodeDecodeError dans Python 3.6?

existe-t-il un moyen de dire à Python3 d'imprimer tout dans utf-8? tout comme je l'ai fait en Python2?

4
Umair

On dirait que votre locale est cassée et a un autre octet-> problème Unicode. La chose que vous avez fait pour Python 2.7 est un hack qui n'a masqué que le vrai problème (il y a une raison pour laquelle vous devez reload sys pour le faire fonctionner).

Pour corriger vos paramètres régionaux, essayez de taper locale à partir de la ligne de commande. Cela devrait ressembler à:

LANG=en_GB.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_ALL=

locale dépend de la configuration correcte de LANG. Python utilise efficacement locale pour déterminer le codage à utiliser lors de l'écriture dans stdout in. S'il ne peut pas le résoudre, il utilise par défaut ASCII.

Vous devez d'abord essayer de corriger vos paramètres régionaux. Si locale erreurs, assurez-vous que vous avez installé le module linguistique correct pour votre région.

Si tout le reste échoue, vous pouvez toujours corriger Python en définissant PYTHONIOENCODING=UTF-8. Cela devrait être utilisé en dernier recours car vous masquerez à nouveau les problèmes.

Si Python génère toujours une erreur après avoir défini PYTHONIOENCODING, veuillez mettre à jour votre question avec le stacktrace. Il y a de fortes chances que vous ayez une conversion implicite en cours.

12
Alastair McCormack

Pour une solution Python uniquement, vous devrez recréer votre objet sys.stdout:

import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())

Après cela, une print("hello world") normale devrait être encodée automatiquement en UTF-8.

Mais vous devriez essayer de découvrir pourquoi votre terminal est défini sur un encodage aussi étrange (que Python essaie simplement d'adopter). Peut-être que votre système d'exploitation est mal configuré d'une manière ou d'une autre.

EDIT: Lors de mes tests, la suppression de la variable env LANG a produit pour moi le paramètre étrange pour l'encodage stdout:

LANG= python3
import sys
sys.stdout.encoding

imprimé 'ANSI_X3.4-1968'.

Donc je suppose que vous voudrez peut-être définir votre LANG sur quelque chose comme en_US.UTF-8. Votre programme terminal ne semble pas faire cela.

1
Alfe

J'ai eu ce problème lors de l'utilisation de Python dans un conteneur Docker basé sur Ubuntu 18.04. Il semblait s'agir d'un problème de paramètres régionaux, qui a été résolu en ajoutant ce qui suit au Dockerfile:

ENV LANG C.UTF-8
0
Daniel