Python, Unicode, og Windows-konsollen

stemmer
110

Når jeg prøver å skrive ut en Unicode-streng i et Windows-konsoll, får jeg en UnicodeEncodeError: 'charmap' codec can't encode character ....feil. Jeg antar at dette er fordi Windows konsollen ikke aksepterer Unicode-bare tegn. Hva er den beste vei rundt dette? Er det noen måte jeg kan gjøre Python automatisk ut en ?i stedet for å mislykkes i denne situasjonen?

Edit: Jeg bruker Python 2.5.


Merk: @ LasseV.Karlsen svar med haken er slags utdatert (fra 2008). Vennligst bruk løsninger / svar / forslag nedenfor med forsiktighet !!

@JFSebastian svaret er mer relevant som i dag (06.01.2016).

Publisert på 07/08/2008 klokken 22:26
kilden bruker
På andre språk...                            


13 svar

stemmer
53

Oppdatering: Python 3.6 implementerer PEP 528: Endre Windows konsollen koding til UTF-8 : standard konsollen på Windows vil nå godta alle Unicode-tegn. Internt, bruker den samme Unicode API som den win-unicode-consolepakken som nevnes nedenfor . print(unicode_string)skal bare fungere nå.


Jeg får en UnicodeEncodeError: 'charmap' codec can't encode character... feilmelding.

Feilen gjør at Unicode-tegn som du prøver å skrive ut ikke kan representeres ved hjelp av gjeldende ( chcp) konsollen tegnkoding. Kodesiden er ofte 8-bits koding, slik som cp437det kan representere bare ~ 0x100 tegn fra ~ 1M Unicode tegn:

>>> u "\ N {EURO SIGN}." Kode ( 'cp437')
Tilbakesporings (siste samtale sist):
...
UnicodeEncodeError: 'charmap' codec kan ikke kode tegnet '\ u20ac' i posisjon 0:
tegnet kart til 

Jeg antar at dette er fordi Windows konsollen ikke aksepterer Unicode-bare tegn. Hva er den beste vei rundt dette?

Windows konsollen godtar Unicode-tegn, og det kan til og med vise dem (bare BMP) hvis det tilsvarende skriften er konfigurert . WriteConsoleW()API skal brukes som foreslått i @Daira Hopwood svar . Det kan kalles transparent dvs. du trenger ikke å, og bør ikke endre skriptene hvis du bruker win-unicode-consolepakken :

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

Se Hva er greia med Python 3.4, Unicode, ulike språk og Windows?

Er det noen måte jeg kan gjøre Python automatisk ut en ?i stedet for å mislykkes i denne situasjonen?

Hvis det er nok til å erstatte alle unencodable tegn med ?i ditt tilfelle så kan du sette PYTHONIOENCODINGenvvar :

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

I Python 3.6+, kodingen er spesifisert av PYTHONIOENCODINGdet envvar ignoreres for interaktive konsoll buffere med mindre PYTHONLEGACYWINDOWSIOENCODINGenvvar er innstilt på en ikke-tom streng.

Svarte 24/08/2015 kl. 07:35
kilden bruker

stemmer
32

Merk: Dette svaret er slags utdatert (fra 2008). Vennligst bruk løsningen under forsiktig !!


Her er en side som beskriver problemet og en løsning (søk på siden for teksten Wrapping sys.stdout inn en forekomst ):

PrintFails - Python Wiki

Her er en kode utdrag fra denne siden:

$ 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
  Б
  Б

Det er litt mer informasjon om den siden, vel verdt å lese.

Svarte 07/08/2008 kl. 22:32
kilden bruker

stemmer
25

Til tross for de andre plausible-klingende svar som foreslår å endre koden siden til 65001, som ikke fungerer . (Også, endre standard koding hjelp sys.setdefaultencodinger ikke en god idé .)

Se på dette spørsmålet for detaljer og kode som ikke fungerer.

Svarte 09/01/2011 kl. 05:07
kilden bruker

stemmer
14

Hvis du ikke er interessert i å få en pålitelig representasjon av dårlig karakter (e) du kan bruke noe sånt som dette (jobber med python> = 2.6, inkludert 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}")

Den dårlige karakter (er) i strengen vil bli konvertert i en representasjon som er utskrivbare av Windows konsollen.

Svarte 19/05/2012 kl. 18:48
kilden bruker

stemmer
10

Den under koden vil gjøre Python utgang til konsoll som UTF-8 selv på Windows.

Konsollen vil vise tegnene godt på Windows 7, men på Windows XP vil ikke vise dem godt, men minst det vil fungere, og det viktigste du vil ha en konsekvent utgang fra skriptet på alle plattformer. Du vil være i stand til å omdirigere utdataene til en fil.

Nedenfor koden ble testet med Python 2.6 på 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"
Svarte 06/01/2010 kl. 13:38
kilden bruker

stemmer
3

Bare skriv inn denne koden i kommandolinjen før du utfører Python-skript:

chcp 65001 & set PYTHONIOENCODING=utf-8
Svarte 02/10/2018 kl. 22:11
kilden bruker

stemmer
3

For Python to forsøk:

print unicode(string, 'unicode-escape')

For Python tre forsøk:

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

Eller prøv vinn-Unicode-konsollen:

pip install win-unicode-console
py -mrun your_script.py
Svarte 24/08/2017 kl. 18:00
kilden bruker

stemmer
3

Som Giampaolo Rodolà svar, men enda mer skitten: Jeg virkelig, virkelig har tenkt å bruke lang tid (snart) å forstå hele emnet kodinger og hvordan de gjelder for Windoze konsoller,

For øyeblikket jeg ville bare sthg som ville bety programmet mitt ville ikke krasje, og som jeg forsto ... og også som ikke involverer import av altfor mange eksotiske moduler (spesielt jeg bruker Jython, så halvparten av tiden en Python modulen viser seg faktisk ikke å være tilgjengelig).

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

NB "pr" er kortere å skrive enn "print" (og mye kortere å skrive enn "safeprint") ...!

Svarte 09/03/2016 kl. 22:14
kilden bruker

stemmer
2

Årsaken til problemet er IKKE Win konsollen ikke er villig til å akseptere Unicode (som det gjør dette siden jeg gjette Win2k som standard). Det er standard system koding. Prøv denne koden og se hva det gir deg:

import sys
sys.getdefaultencoding()

hvis det står ascii, er det din sak ;-) Du må opprette en fil som heter sitecustomize.py og setter det under python banen (jeg setter den under /usr/lib/python2.5/site-packages, men det er differen på Win - det er c: \ python \ lib \ site-pakker eller noe), med følgende innhold:

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

og kanskje kan det være lurt å angi koding i filene dine også:

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

Edit: mer info finner du i utmerket dykk inn i Python bok

Svarte 11/08/2008 kl. 17:58
kilden bruker

stemmer
1

TL; DR:

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

Jeg løp inn i dette selv, arbeider på en Twitch chat (IRC) bot. (Python 2.7 nyeste)

Jeg ønsket å analysere chatte-meldinger for å svare ...

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

men også skrive dem trygt til konsollen i en lesbar format:

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

Dette rettet spørsmålet om bot UnicodeEncodeError: 'charmap'kastefeil og erstattet Unicode-tegn med ?.

Svarte 01/07/2018 kl. 15:52
kilden bruker

stemmer
1

Python 3.6 windows7: Det er flere måte å lansere en python du kan bruke python konsollen (som har en python logo på den) eller Windows konsollen (det er skrevet cmd.exe på det).

Jeg kunne ikke skrive ut utf8 tegn i windows konsollen. Skrive UTF-8 tegn kaste meg denne feilmeldingen:

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 

Etter prøving og feiling for å forstå svaret ovenfor jeg oppdaget at det var bare en innstilling problem. Høyreklikk på toppen av CMD konsoll vinduer, på fanen fontvalgte lucida konsollen.

Svarte 11/05/2017 kl. 20:08
kilden bruker

stemmer
1

Slags relatert på svaret ved JF Sebastian, men mer direkte.

Hvis du har dette problemet ved utskrift til konsollen / terminalen, så gjør dette:

>set PYTHONIOENCODING=UTF-8
Svarte 16/12/2015 kl. 07:53
kilden bruker

stemmer
0

James Sulak spurte:

Er det noen måte jeg kan gjøre Python automatisk ut en? i stedet for å mislykkes i denne situasjonen?

Andre løsninger anbefaler vi forsøke å endre Windows-miljøet eller erstatte Pythons print()funksjon. Svaret nedenfor kommer nærmere å oppfylle Sulak ønske.

I Windows 7, kan Python 3.5 gjøres for å skrive ut Unicode uten å kaste en UnicodeEncodeErrorsom følger:

    I stedet for:     print(text)
    erstatning:     print(str(text).encode('utf-8'))

I stedet for å kaste et unntak, viser Python nå unprintable Unicode-tegn som \ XNN hex koder, f.eks:

  Halmalo n \ XE2 \ x80 \ x99 \ xc3 \ xa9tait pluss qu \ XE2 \ x80 \ x99un punkt noir

I stedet for

  Halmalo n'était pluss qu'un punkt noir

Riktignok er den sistnevnte foretrukne alt annet like , men ellers er den tidligere helt nøyaktig for diagnostiske meldinger. Fordi den viser et Unicode som bokstavelig byte-verdier førstnevnte kan også hjelpe til ved diagnostisering kode / dekode problemer.

Merk: Den str()samtalen ovenfor er nødvendig fordi ellers encode()får Python til å avvise en Unicode karakter som en tuppel av tall.

Svarte 14/05/2016 kl. 17:47
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more