Python, Unicode, και η κονσόλα των Windows

ψήφοι
104

Όταν προσπαθώ να εκτυπώσετε μια σειρά Unicode στην κονσόλα των Windows, παίρνω ένα UnicodeEncodeError: 'charmap' codec can't encode character ....λάθος. Υποθέτω ότι αυτό οφείλεται στο γεγονός ότι η κονσόλα των Windows δεν δέχεται Unicode μόνο χαρακτήρες. Ποιος είναι ο καλύτερος τρόπος γύρω από αυτό; Υπάρχει κάποιος τρόπος που μπορώ να κάνω Python εκτυπώνει αυτόματα μια εκεί ?, αντί της αποτυχίας σε αυτή την κατάσταση;

Επεξεργασία: Είμαι με τη χρήση Python 2.5.


Σημείωση: @ LasseV.Karlsen απάντηση με το σημάδι είναι το είδος των παρωχημένων (από το 2008). Παρακαλούμε χρησιμοποιήστε τις λύσεις / απαντήσεις / προτάσεις παρακάτω με προσοχή !!

@JFSebastian απάντηση είναι πιο σημαντική από σήμερα (6 Ιανουαρίου του 2016).

Δημοσιεύθηκε 07/08/2008 στις 21:26
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
29

Σημείωση: Αυτή η απάντηση είναι το είδος των παρωχημένων (από το 2008). Παρακαλούμε χρησιμοποιήστε την λύση κάτω με προσοχή !!


Εδώ είναι μια σελίδα που περιγράφει με λεπτομέρειες το πρόβλημα και μια λύση (ψάξετε τη σελίδα για το κείμενο sys.stdout Αναδίπλωση σε μια περίπτωση ):

PrintFails - Python Wiki

Εδώ είναι ένας κωδικός απόσπασμα από αυτήν τη σελίδα:

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

Υπάρχουν κάποιες περισσότερες πληροφορίες σε αυτή τη σελίδα, αλλά αξίζει μια ανάγνωση.

Απαντήθηκε 07/08/2008 στις 21:32
πηγή χρήστη

ψήφοι
1

Η αιτία του προβλήματός σας είναι ΟΧΙ η Νίκη κονσόλα δεν είναι διατεθειμένοι να δεχτούν Unicode (όπως το κάνει αυτό διότι υποθέτω Win2k από προεπιλογή). Είναι η κωδικοποίηση προεπιλεγμένο σύστημα. Δοκιμάστε αυτόν τον κώδικα και να δούμε τι σας δίνει:

import sys
sys.getdefaultencoding()

αν λέει ascii, δεν υπάρχει λόγος σας ;-) Θα πρέπει να δημιουργήσετε ένα αρχείο που ονομάζεται sitecustomize.py και να το βάλετε κάτω διαδρομή python (το έβαλα κάτω /usr/lib/python2.5/site-packages, αλλά αυτό είναι Διαφοροποιημένες για Νίκη - είναι c: \ python \ lib \ τοποθεσία πακέτα ή κάτι τέτοιο), με το εξής περιεχόμενο:

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

και ίσως να θέλετε να ορίσετε την κωδικοποίηση των αρχείων σας, καθώς:

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

Επεξεργασία: περισσότερες πληροφορίες μπορούν να βρεθούν σε άριστη την κατάδυση στο βιβλίο Python

Απαντήθηκε 11/08/2008 στις 16:58
πηγή χρήστη

ψήφοι
9

Ο παρακάτω κώδικας θα κάνει έξοδο Python για να παρηγορήσει ως UTF-8 ακόμη στα Windows.

Η κονσόλα θα εμφανίσει τους χαρακτήρες και για τα Windows 7, αλλά για τα Windows XP δεν θα τους εμφανίσει καλά, αλλά τουλάχιστον θα λειτουργήσει και το πιο σημαντικό θα έχετε μια συνεπή εξόδου από το σενάριό σας σε όλες τις πλατφόρμες. Θα είστε σε θέση να ανακατευθύνει την έξοδο σε ένα αρχείο.

Παρακάτω κωδικό δοκιμάστηκε με την Python 2.6 στα 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"
Απαντήθηκε 06/01/2010 στις 12:38
πηγή χρήστη

ψήφοι
22

Παρά τις άλλες εύλογες άκουσμα απαντήσεις που προτείνουν την αλλαγή του κωδικού της σελίδας για να 65001, ότι δεν λειτουργεί . (Επίσης, αλλάζοντας την προεπιλεγμένη κωδικοποίηση χρησιμοποιώντας sys.setdefaultencodingείναι δεν είναι καλή ιδέα .)

Δείτε αυτή την ερώτηση για τις λεπτομέρειες και τον κωδικό που λειτουργεί.

Απαντήθηκε 09/01/2011 στις 04:07
πηγή χρήστη

ψήφοι
11

Αν δεν σας ενδιαφέρει να πάρει μια αξιόπιστη αναπαράσταση του κακού χαρακτήρα (ες) που μπορείτε να χρησιμοποιήσετε κάτι σαν αυτό (που εργάζονται με python> = 2.6, συμπεριλαμβανομένων 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}")

Το κακό χαρακτήρα (ες) στη συμβολοσειρά θα μετατραπεί σε μια παράσταση που είναι εκτυπώσιμο από την κονσόλα των Windows.

Απαντήθηκε 19/05/2012 στις 17:48
πηγή χρήστη

ψήφοι
50

Ενημέρωση: Python 3.6 υλοποιεί PEP 528: Αλλαγή των Windows κονσόλα κωδικοποίηση σε UTF-8 : η προεπιλεγμένη κονσόλα για τα Windows θα δεχτεί τώρα όλα Unicode χαρακτήρες. Εσωτερικά, χρησιμοποιεί την ίδια Unicode API όπως το win-unicode-consoleπακέτο που αναφέρονται παρακάτω . print(unicode_string)πρέπει απλά να λειτουργήσει τώρα.


Παίρνω ένα UnicodeEncodeError: 'charmap' codec can't encode character... λάθος.

Το σφάλμα σημαίνει ότι Unicode χαρακτήρες που προσπαθείτε να εκτυπώσετε δεν μπορεί να αναπαρασταθεί με τη χρήση του ρεύματος ( chcp) κονσόλα κωδικοποίηση χαρακτήρων. Η κωδικοσελίδα είναι συχνά 8-bit κωδικοποίηση όπως cp437ότι μπορεί να αντιπροσωπεύουν μόνο το ~ 0x100 χαρακτήρες από χαρακτήρες ~ 1Μ Unicode:

>>> u "\ Ν {EURO SIGN}". Κωδικοποιούν ( 'cp437')
Traceback (πιο πρόσφατη κλήση τελευταία):
...
UnicodeEncodeError: «charmap» κωδικοποίηση δεν μπορεί να κωδικοποιήσει χαρακτήρα «\ u20ac» στη θέση 0:
χαρακτήρα χάρτες για να 

Υποθέτω ότι αυτό οφείλεται στο γεγονός ότι η κονσόλα των Windows δεν δέχεται Unicode μόνο χαρακτήρες. Ποιος είναι ο καλύτερος τρόπος γύρω από αυτό;

Κονσόλα των Windows δέχεται Unicode χαρακτήρες και μπορεί ακόμη και να τα εμφανίσει (μόνο BMP) αν η αντίστοιχη γραμματοσειρά έχει ρυθμιστεί . WriteConsoleW()API θα πρέπει να χρησιμοποιείται όπως προτείνεται στην απάντηση @Daira Hopwood του . Μπορεί να ονομάζεται διαφάνεια δηλαδή, δεν χρειάζεται και δεν πρέπει να τροποποιούν τα σενάρια σας, αν χρησιμοποιείτε win-unicode-consoleτο πακέτο :

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

Δείτε Ποια είναι η διαπραγμάτευση με την Python 3.4, Unicode, διαφορετικές γλώσσες και τα Windows;

Υπάρχει κάποιος τρόπος που μπορώ να κάνω Python εκτυπώνει αυτόματα μια εκεί ?, αντί της αποτυχίας σε αυτή την κατάσταση;

Αν είναι αρκετό για να αντικαταστήσει όλα τα unencodable χαρακτήρες με ?την περίπτωση σας, τότε μπορείτε να ορίσετε PYTHONIOENCODINGenvvar :

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

Στην Python 3.6+, η κωδικοποίηση που ορίζεται από PYTHONIOENCODINGenvvar αγνοείται για διαλογική ρυθμιστικά κονσόλα εκτός PYTHONLEGACYWINDOWSIOENCODINGenvvar έχει οριστεί σε ένα μη-κενό string.

Απαντήθηκε 24/08/2015 στις 06:35
πηγή χρήστη

ψήφοι
1

Είδος που σχετίζονται με την απάντηση από τον JF Sebastian, αλλά πιο άμεση.

Εάν αντιμετωπίζετε αυτό το πρόβλημα κατά την εκτύπωση στην κονσόλα / τερματικό σταθμό, στη συνέχεια, να το κάνετε αυτό:

>set PYTHONIOENCODING=UTF-8
Απαντήθηκε 16/12/2015 στις 05:53
πηγή χρήστη

ψήφοι
2

Όπως απάντηση Giampaolo Rodolà, αλλά ακόμα πιο βρώμικο: Πραγματικά, πραγματικά σκοπεύετε να περάσετε ένα μεγάλο χρονικό διάστημα (σύντομα) την κατανόηση του όλο θέμα των κωδικοποιήσεων και πώς εφαρμόζεται σε Windoze κονσόλες,

Προς το παρόν θα ήθελα απλώς sthg που θα σήμαινε το πρόγραμμά μου δεν θα συντριβή, και που κατάλαβα ... αλλά και η οποία δεν περιλαμβάνει την εισαγωγή πάρα πολλά εξωτικά ενότητες (ιδίως Είμαι με τη χρήση Jython, έτσι ώστε το ήμισυ του χρόνου η Python ενότητα αποδεικνύεται στην πραγματικότητα δεν είναι διαθέσιμο).

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

Σημείωση: «pr» είναι μικρότερη από ό, τι να πληκτρολογήσετε «εκτύπωση» (και αρκετά μικρότερη από ό, τι να πληκτρολογήσετε «safeprint») ...!

Απαντήθηκε 09/03/2016 στις 20:14
πηγή χρήστη

ψήφοι
0

James Sulak ρώτησε,

Υπάρχει κάποιος τρόπος που μπορώ να κάνω Python εκτυπώσετε αυτόματα εκεί; αντί της αποτυχίας σε αυτή την κατάσταση;

Άλλες λύσεις που προτείνουμε προσπαθούμε να τροποποιήσουν το περιβάλλον των Windows ή την αντικατάσταση της Python print()λειτουργία. Η παρακάτω απάντηση έρχεται πιο κοντά στην εκπλήρωση αίτημα Sulak του.

Στα Windows 7, Python 3.5 μπορεί να γίνει για να εκτυπώσετε Unicode, χωρίς να ρίχνει ένα UnicodeEncodeErrorως εξής:

    Στη θέση του:     print(text)
    υποκατάστατο:     print(str(text).encode('utf-8'))

Αντί να ρίχνουν μια εξαίρεση, Python εμφανίζει τώρα ατύπωτος χαρακτήρες Unicode, όπως \ Xnn κωδικούς εξάγωνο, όπως:

  Halmalo n \ XE2 \ x80 \ x99 \ XC3 \ xa9tait συν qu \ XE2 \ x80 \ x99un σημείο Noir

Αντί

  Halmalo n'était συν το σημείο qu'un νουάρ

Σύμφωνοι, το τελευταίο είναι προτιμότερο ceteris paribus , αλλά κατά τα άλλα η πρώτη είναι απόλυτα ακριβής για διαγνωστικά μηνύματα. Επειδή εμφανίζει Unicode όπως εκτιμά κυριολεκτική byte ο πρώην μπορεί επίσης να βοηθήσει στη διάγνωση προβλημάτων κωδικοποίηση / αποκωδικοποίηση.

Σημείωση: Η str()κλήση παραπάνω είναι απαραίτητη γιατί αλλιώς encode()προκαλεί Python να απορρίψει ένα χαρακτήρα Unicode ως πλειάδα των αριθμών.

Απαντήθηκε 14/05/2016 στις 16:47
πηγή χρήστη

ψήφοι
1

Python 3.6 windows7: Υπάρχει πολλές τρόπος για να ξεκινήσει μια python θα μπορούσατε να χρησιμοποιήσετε την κονσόλα Python (η οποία έχει ένα λογότυπο python σε αυτό) ή την κονσόλα παράθυρα (είναι γραμμένο cmd.exe σε αυτό).

Δεν θα μπορούσα να εκτυπώσετε utf8 χαρακτήρες στην κονσόλα παράθυρα. Εκτύπωση utf-8 χαρακτήρες ρίξει με αυτό το σφάλμα:

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 

Μετά από προσπάθεια και την αποτυχία να κατανοήσει την απάντηση παραπάνω ανακάλυψα ότι ήταν μόνο ένα πρόβλημα ρύθμιση. Κάντε δεξί κλικ στο πάνω μέρος των cmd παράθυρα κονσόλας, στην καρτέλα fontεπέλεξε Lucida κονσόλα.

Απαντήθηκε 11/05/2017 στις 19:08
πηγή χρήστη

ψήφοι
2

Για Python 2 δοκιμάσετε:

print unicode(string, 'unicode-escape')

Για Python 3 δοκιμή:

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

Ή δοκιμάστε win-unicode-κονσόλα:

pip install win-unicode-console
py -mrun your_script.py
Απαντήθηκε 24/08/2017 στις 17:00
πηγή χρήστη

ψήφοι
1

TL? DR:

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

Έτρεξα σε αυτό τον εαυτό μου, που εργάζονται για μια σύσπαση συνομιλία (IRC) bot. (Python 2.7 τελευταίο)

Ήθελα να αναλύσει μηνύματα chat, προκειμένου να ανταποκριθεί ...

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

αλλά και να εκτυπώσετε με ασφάλεια στην κονσόλα σε μορφή αναγνώσιμη από τον άνθρωπο:

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

Αυτό διορθωθεί το πρόβλημα των bot ρίχνουν UnicodeEncodeError: 'charmap'τα λάθη και να αντικατασταθούν τα unicode χαρακτήρες με ?.

Απαντήθηκε 01/07/2018 στις 14:52
πηγή χρήστη

ψήφοι
3

Απλά εισάγετε αυτόν τον κωδικό στην γραμμή εντολών πριν την εκτέλεση script python:

chcp 65001 & set PYTHONIOENCODING=utf-8
Απαντήθηκε 02/10/2018 στις 21:11
πηγή χρήστη

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