Question

Lorsque j'essaie d'imprimer une chaîne Unicode dans une console Windows, j'obtiens un UnicodeEncodeError: 'charmap' codec can't encode character .... erreur.Je suppose que c'est parce que la console Windows n'accepte pas les caractères Unicode uniquement.Quelle est la meilleure façon de contourner ce problème ?Existe-t-il un moyen pour que Python imprime automatiquement un ? au lieu d'échouer dans cette situation ?

Modifier: J'utilise Python 2.5.


Note: La réponse de @LasseV.Karlsen avec la coche est en quelque sorte obsolète (à partir de 2008).Veuillez utiliser les solutions/réponses/suggestions ci-dessous avec précaution !!

@JFSebastian répond est plus pertinent à ce jour (6 janvier 2016).

Était-ce utile?

La solution

Note: Cette réponse est en quelque sorte obsolète (à partir de 2008).Veuillez utiliser la solution ci-dessous avec précaution !!


Voici une page qui détaille le problème et une solution (recherchez le texte sur la page Encapsuler sys.stdout dans une instance):

Échecs d'impression — Python Wiki

Voici un extrait de code de cette page :

$ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line'
  UTF-8
  <type 'unicode'> 2
  Б
  Б

  $ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line' | cat
  None
  <type 'unicode'> 2
  Б
  Б

Il y a plus d'informations sur cette page, qui valent la peine d'être lu.

Autres conseils

Mise à jour: Python3.6 met en oeuvre PEP 528 :Changer le codage de la console Windows en UTF-8: la console par défaut sous Windows acceptera désormais tous les caractères Unicode. En interne, il utilise la même API Unicode que le win-unicode-console forfait mentionné ci-dessous. print(unicode_string) devrait juste fonctionner maintenant.


J'ai un UnicodeEncodeError: 'charmap' codec can't encode character... erreur.

L'erreur signifie que les caractères Unicode que vous essayez d'imprimer ne peuvent pas être représentés à l'aide du format actuel (chcp) encodage des caractères de la console.La page de codes est souvent codée sur 8 bits, comme cp437 qui ne peut représenter qu'environ 0x100 caractères à partir d'environ 1 million de caractères Unicode :

>>> u"\N{EURO SIGN}".encode('cp437')
Traceback (most recent call last):
...
UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position 0:
character maps to 

Je suppose que c'est parce que la console Windows n'accepte pas les caractères Unicode uniquement.Quelle est la meilleure façon de contourner ce problème ?

La console Windows accepte les caractères Unicode et peut même les afficher (BMP uniquement) si la police correspondante est configurée. WriteConsoleW() L'API doit être utilisée comme suggéré dans Réponse de @Daira Hopwood.Il peut être appelé de manière transparente, c'est-à-dire que vous n'avez pas besoin et ne devez pas modifier vos scripts si vous utilisez win-unicode-console emballer:

T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py

Voir Quel est le problème avec Python 3.4, Unicode, les différents langages et Windows ?

Y a-t-il un moyen de faire imprimer automatiquement Python ? au lieu d'échouer dans cette situation ?

S'il suffit de remplacer tous les caractères non codables par ? dans votre cas, vous pouvez définir PYTHONIOENCODING envvar:

T:\> set PYTHONIOENCODING=:replace
T:\> python3 -c "print(u'[\N{EURO SIGN}]')"
[?]

Dans Python 3.6+, l'encodage spécifié par PYTHONIOENCODING envvar est ignoré pour les tampons de console interactive, sauf si PYTHONLEGACYWINDOWSIOENCODING envvar est défini sur une chaîne non vide.

Malgré les autres réponses plausibles suggérant de changer la page de codes en 65001, cela ne marche pas.(En outre, en modifiant l'encodage par défaut à l'aide de sys.setdefaultencoding est pas une bonne idée.)

Voir cette question pour plus de détails et du code qui fonctionne.

Si vous ne souhaitez pas obtenir une représentation fiable du ou des mauvais caractères, vous pouvez utiliser quelque chose comme ceci (en travaillant avec python >= 2.6, y compris 3.x) :

from __future__ import print_function
import sys

def safeprint(s):
    try:
        print(s)
    except UnicodeEncodeError:
        if sys.version_info >= (3,):
            print(s.encode('utf8').decode(sys.stdout.encoding))
        else:
            print(s.encode('utf8'))

safeprint(u"\N{EM DASH}")

Le(s) mauvais caractère(s) de la chaîne seront convertis en une représentation imprimable par la console Windows.

Le code ci-dessous générera une sortie Python sur la console au format UTF-8, même sous Windows.

La console affichera bien les caractères sous Windows 7 mais sous Windows XP, elle ne les affichera pas bien, mais au moins cela fonctionnera et, plus important encore, vous aurez une sortie cohérente de votre script sur toutes les plateformes.Vous pourrez rediriger la sortie vers un fichier.

Le code ci-dessous a été testé avec Python 2.6 sous Windows.


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import codecs, sys

reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()

if sys.platform == 'win32':
    try:
        import win32console 
    except:
        print "Python Win32 Extensions module is required.\n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)\n"
        exit(-1)
    # win32console implementation  of SetConsoleCP does not return a value
    # CP_UTF8 = 65001
    win32console.SetConsoleCP(65001)
    if (win32console.GetConsoleCP() != 65001):
        raise Exception ("Cannot set console codepage to 65001 (UTF-8)")
    win32console.SetConsoleOutputCP(65001)
    if (win32console.GetConsoleOutputCP() != 65001):
        raise Exception ("Cannot set console output codepage to 65001 (UTF-8)")

#import sys, codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

print "This is an Е乂αmp١ȅ testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points.\n"

Comme la réponse de Giampaolo Rodolà, mais encore plus sale :J'ai vraiment, vraiment l'intention de passer beaucoup de temps (bientôt) à comprendre tout le sujet des encodages et comment ils s'appliquent aux consoles Windoze,

Pour le moment, je voulais juste quelque chose qui ferait que mon programme ne crasherait PAS, et que j'ai compris...et aussi qui n'impliquait pas d'importer trop de modules exotiques (en particulier j'utilise Jython, donc la moitié du temps, un module Python s'avère en fait indisponible).

def pr(s):
    try:
        print(s)
    except UnicodeEncodeError:
        for c in s:
            try:
                print( c, end='')
            except UnicodeEncodeError:
                print( '?', end='')

NB "pr" est plus court à taper que "print" (et un peu plus court à taper que "safeprint")...!

Entrez simplement ce code en ligne de commande avant d'exécuter le script python :

chcp 65001 & set PYTHONIOENCODING=utf-8

Pour Python 2, essayez :

print unicode(string, 'unicode-escape')

Pour Python 3, essayez :

import os
string = "002 Could've Would've Should've"
os.system('echo ' + string)

Ou essayez win-unicode-console :

pip install win-unicode-console
py -mrun your_script.py

La cause de votre problème est PAS la console Win ne veut pas accepter Unicode (comme elle le fait puisque je suppose que Win2k par défaut).C'est l'encodage système par défaut.Essayez ce code et voyez ce qu'il vous donne :

import sys
sys.getdefaultencoding()

S'il indique ASCII, il y a votre cause ;-) Vous devez créer un fichier appelé SiteSustomalize.py et le mettre sous Python Path (je l'ai mis sous /usr/lib/python2.5/site-packages, mais cela est différent Win - c'est C: python lib site-packages ou quelque chose), avec le contenu suivant:

import sys
sys.setdefaultencoding('utf-8')

et peut-être souhaiterez-vous également spécifier l'encodage de vos fichiers :

# -*- coding: UTF-8 -*-
import sys,time

Modifier:plus d'informations peuvent être trouvées dans l'excellent livre Dive into Python

TL;DR :

print(yourstring.encode('ascii','replace'));

J'ai moi-même rencontré ce problème en travaillant sur un bot de chat Twitch (IRC).(Python 2.7 dernier)

Je voulais analyser les messages de chat afin de répondre...

msg = s.recv(1024).decode("utf-8")

mais imprimez-les également en toute sécurité sur la console dans un format lisible par l'homme :

print(msg.encode('ascii','replace'));

Cela a corrigé le problème du lancement du bot UnicodeEncodeError: 'charmap' erreurs et remplacé les caractères Unicode par ?.

Un peu lié à la réponse de J.F.Sebastian, mais plus direct.

Si vous rencontrez ce problème lors de l'impression sur la console/le terminal, procédez comme suit :

>set PYTHONIOENCODING=UTF-8

Python 3.6 Windows7 :Il existe plusieurs façons de lancer un python, vous pouvez utiliser la console Python (qui porte un logo Python) ou la console Windows (c'est écrit cmd.exe dessus).

Je n'ai pas pu imprimer les caractères utf8 dans la console Windows.L'impression de caractères utf-8 me renvoie cette erreur :

OSError: [winError 87] The paraneter is incorrect 
Exception ignored in: (_io-TextIOwrapper name='(stdout)' mode='w' ' encoding='utf8') 
OSError: [WinError 87] The parameter is incorrect 

Après avoir essayé et échoué à comprendre la réponse ci-dessus, j'ai découvert qu'il ne s'agissait que d'un problème de configuration.Faites un clic droit en haut des fenêtres de la console cmd, sur l'onglet font J'ai choisi la console Lucida.

James Sulak a demandé :

Existe-t-il un moyen pour que Python imprime automatiquement un ?au lieu d'échouer dans cette situation ?

D'autres solutions recommandent d'essayer de modifier l'environnement Windows ou de remplacer celui de Python. print() fonction.La réponse ci-dessous se rapproche davantage de la demande de Sulak.

Sous Windows 7, Python 3.5 peut être configuré pour imprimer Unicode sans lancer de code. UnicodeEncodeError comme suit:

Au lieu de:print(text)
remplaçant: print(str(text).encode('utf-8'))

Au lieu de lever une exception, Python affiche désormais les caractères Unicode non imprimables \xNN codes hexadécimaux, par exemple :

  Halmalo n\xe2\x80\x99\xc3\xa9était plus qu\xe2\x80\x99un point noir

Au lieu de

  Halmalo n'était plus qu'un point noir

Certes, ce dernier est préférable ceteris paribus, mais sinon, le premier est tout à fait précis pour les messages de diagnostic.Parce qu'il affiche Unicode sous forme de valeurs d'octets littérales, le premier peut également aider à diagnostiquer les problèmes d'encodage/décodage.

Note: Le str() l'appel ci-dessus est nécessaire car sinon encode() amène Python à rejeter un caractère Unicode en tant que tuple de nombres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top