पायथन, यूनिकोड और विंडोज कंसोल


146

जब मैं विंडोज कंसोल में यूनिकोड स्ट्रिंग प्रिंट करने की कोशिश करता हूं, तो मुझे एक UnicodeEncodeError: 'charmap' codec can't encode character ....त्रुटि मिलती है । मुझे लगता है कि यह इसलिए है क्योंकि विंडोज कंसोल यूनिकोड-केवल वर्णों को स्वीकार नहीं करता है। इसके आसपास सबसे अच्छा तरीका क्या है? क्या कोई तरीका है जिससे मैं पायथन ?को इस स्थिति में विफल होने के बजाय स्वचालित रूप से प्रिंट कर सकता हूं ?

संपादित करें: मैं अजगर 2.5 का उपयोग कर रहा हूं।


नोट: @ LasseV.Karlsen चेकमार्क के साथ पुराना (2008 से) पुराना है। कृपया ध्यान से नीचे दिए गए समाधान / उत्तर / सुझाव का उपयोग करें !!

@JFSebastian का उत्तर आज (6 जनवरी 2016) से अधिक प्रासंगिक है।


आप पायथन के किस संस्करण पर हैं? मैंने संदर्भ देखा है कि यह 2.4.3 में टूट गया था और 2.4.4 में तय किया गया था।
Stu

3
संबंधित: Bugs.python.org/issue1602
jfs

जाँच इस बाहर।
सोयोरेना

1
सबसे सरल उत्तर जो मुझे मिला वह टाइप करना है: chcp 65001 को cmd में phhton का उपयोग करने से पहले
Soorena

1
फिर आपको अपना स्वीकृत उत्तर बदलना चाहिए ...
Mr_and_Mrs_D

जवाबों:


38

नोट: यह उत्तर पुराना (2008 से) पुराना है। कृपया ध्यान से नीचे दिए गए समाधान का उपयोग करें !!


यहां एक पृष्ठ है जो समस्या और समाधान का विवरण देता है ( उदाहरण के लिए पाठ को रैपिंग sys.stdout के लिए पृष्ठ खोजें ):

PrintFails - पायथन विकी

यहाँ उस पृष्ठ का एक अंश प्रस्तुत है:

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

उस पृष्ठ पर कुछ और जानकारी है, अच्छी तरह से पढ़ने लायक है।


7
लिंक मर चुका है और जवाब का सार उद्धृत नहीं किया गया था। -1
0xC0000022L

1
जब मैं लपेटने के बारे में दी गई सलाह की कोशिश करता हूं sys.stdout, तो यह गलत चीजों को छापती है। उदाहरण के लिए, एन-डैश के बजाय u'\u2013'बन जाता है û
user2357112

@ user2357112 आपको इसके बारे में एक नया प्रश्न पोस्ट करना होगा। यूनिकोड और सिस्टम कंसोल आवश्यक रूप से सबसे अच्छा संयोजन नहीं है, लेकिन मुझे इस बारे में पर्याप्त जानकारी नहीं है, इसलिए यदि आपको एक निश्चित उत्तर की आवश्यकता है, तो इसके बारे में SO पर यहां एक प्रश्न पोस्ट करें।
लास वी। कार्लसन जू

2
लिंक मर चुका है। कोड का उदाहरण विंडोज कंसोल के लिए गलत है जहां कोडपेज (ओईएम) जैसे कि cp437विंडोज एएनएसआई कोडपेज से अलग है cp1252। कोड UnicodeEncodeError: 'charmap' codec can't encode characterत्रुटि को ठीक नहीं करता है और इससे mojibake हो सकता है, जैसे ا©चुपचाप बदल दिया जाता है ╪º⌐
JFS

73

अपडेट: अजगर 3.6 औजार पीईपी 528: UTF-8 के लिए Windows बदलें एन्कोडिंग कंसोल : विंडोज पर डिफ़ॉल्ट सांत्वना अब सभी यूनिकोड वर्ण को स्वीकार करेंगे। आंतरिक रूप से, यह रूप में एक ही यूनिकोड API का उपयोग करता पैकेज नीचे उल्लेख । बस अब काम करना चाहिए।win-unicode-consoleprint(unicode_string)


मुझे एक UnicodeEncodeError: 'charmap' codec can't encode character... त्रुटि मिलती है ।

त्रुटि का मतलब है कि यूनिकोड वर्ण जिसे आप प्रिंट करने का प्रयास कर रहे हैं, उन्हें वर्तमान ( chcp) कंसोल वर्ण एन्कोडिंग का उपयोग करके नहीं दिखाया जा सकता है । कोडपेज अक्सर 8-बिट एन्कोडिंग होता है जो cp437कि ~ 1M यूनिकोड वर्णों से केवल ~ 0x100 वर्णों का प्रतिनिधित्व कर सकता है:

>>> u "\ N {यूरो हस्ताक्षर}"। सांकेतिक शब्दों में बदलना ('cp437')
ट्रेसबैक (सबसे हालिया कॉल अंतिम):
...
यूनिकोडेनाकोड: 'चार्मैप' कोडक 0 में स्थिति '\ u20ac' को कूटबद्ध नहीं कर सकता है:
चरित्र नक्शे के लिए 

मुझे लगता है कि यह इसलिए है क्योंकि विंडोज कंसोल यूनिकोड-केवल वर्णों को स्वीकार नहीं करता है। इसके आसपास सबसे अच्छा तरीका क्या है?

Windows कंसोल यूनिकोड वर्णों को स्वीकार करता है और यदि संगत फ़ॉन्ट कॉन्फ़िगर किया गया है तो यह उन्हें (BMP केवल) भी प्रदर्शित कर सकता हैWriteConsoleW()एपीआई का उपयोग @Daira हॉपवुड के जवाब में सुझाव के रूप में किया जाना चाहिए । इसे पारदर्शी रूप से कहा जा सकता है, अगर आपको win-unicode-consoleपैकेज का उपयोग करने की आवश्यकता नहीं है और आपको अपनी स्क्रिप्ट को संशोधित नहीं करना चाहिए :

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

देखें कि पायथन 3.4, यूनिकोड, विभिन्न भाषाओं और विंडोज के साथ क्या डील हुई है?

क्या कोई तरीका है जिससे मैं पायथन ?को इस स्थिति में विफल होने के बजाय स्वचालित रूप से प्रिंट कर सकता हूं ?

यदि यह ?आपके मामले में सभी अयोग्य पात्रों को बदलने के लिए पर्याप्त है तो आप PYTHONIOENCODINGenvvar सेट कर सकते हैं :

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

पायथन 3.6+ में, PYTHONIOENCODINGएन्वार द्वारा निर्दिष्ट एन्कोडिंग को इंटरएक्टिव कंसोल बफ़र्स के लिए नजरअंदाज कर दिया जाता है, जब तक कि PYTHONLEGACYWINDOWSIOENCODINGएनवार को गैर-रिक्त स्ट्रिंग पर सेट नहीं किया जाता है।


3
"विंडोज पर डिफ़ॉल्ट कंसोल अब सभी यूनिकोड वर्णों को स्वीकार करेगा" लेकिन आपको कंसोल को कॉन्फ़िगर करने की आवश्यकता है: विंडोज़ के शीर्ष पर राइट क्लिक करें (सीएमडी या अजगर आईडीएल के), डिफ़ॉल्ट में / फ़ॉन्ट "ल्यूसिडा कंसोल" चुनें। (जापानी और चीनी मेरे लिए काम नहीं करते हैं, लेकिन मुझे इसके बिना जीवित रहना चाहिए ...)
जिनसैन

2
@Guillaume: उत्तर में विंडोज कंसोल के बारे में बोल्ड वाक्यांश है : "यदि संबंधित फ़ॉन्ट कॉन्फ़िगर किया गया है।" इस उत्तर में IDLE का उल्लेख नहीं है, लेकिन आपको इसमें फ़ॉन्ट कॉन्फ़िगर करने की आवश्यकता नहीं है (मुझे डिफ़ॉल्ट रूप से IDLE में जापानी और चीनी वर्ण ठीक दिखाई देते हैं। कोशिश करें print('\u4E01'), print('\u6b63'))।
jfs

2
यदि आप विंडोज 10 में भाषा पैक स्थापित करते हैं, तो आप चीनी भी प्राप्त कर सकते हैं। इसमें कंसोल फोंट जोड़े गए हैं जो चीनी का समर्थन करते हैं।
मार्क तोलोनन

28

अन्य प्रशंसनीय-लगने वाले उत्तरों के बावजूद, जो कोड पृष्ठ को 65001 में बदलने का सुझाव देता है, वह काम नहीं करता है । (इसके अलावा, डिफ़ॉल्ट एन्कोडिंग का उपयोग sys.setdefaultencodingकरना एक अच्छा विचार नहीं है ।)

देखें इस सवाल का विवरण और कि काम करता है कोड के लिए।


2
win-unicode-consoleपायथन पैकेज (आपके कोड के आधार पर) आपकी स्क्रिप्ट को संशोधित करने से बचने की अनुमति देता है यदि यह यूनिकोड को सीधे py -mrun your_script.pyकमांड का उपयोग करके प्रिंट करता है ।
jfs

12

यदि आपको बुरे चरित्र (नों) का विश्वसनीय प्रतिनिधित्व प्राप्त करने में कोई दिलचस्पी नहीं है, तो आप कुछ इस तरह से उपयोग कर सकते हैं (3.x सहित python> = 2.6 के साथ काम करना):

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}")

स्ट्रिंग में खराब चरित्र (एस) को एक प्रतिनिधित्व में परिवर्तित किया जाएगा जो विंडोज कंसोल द्वारा प्रिंट करने योग्य है।


.encode('utf8').decode(sys.stdout.encoding)mojibake की ओर जाता है, जैसे u"\N{EM DASH}".encode('utf-8').decode('cp437')->ΓÇö
jfs

बस print(s.encode('utf-8'))संकलक त्रुटियों से बचने का एक बेहतर तरीका हो सकता है। इसके बजाय, आपको अनपेक्षित वर्णों के लिए \ xNN आउटपुट मिलता है, जो मेरे नैदानिक ​​संदेशों के लिए पर्याप्त था।
CODE-REaD

4
यह बहुत बड़ा है, शानदार गलत है। UTF-8 को एन्कोडिंग तो 8-बिट चारसेट के रूप में डिकोड करना a) अक्सर विफल हो जाता है, सभी कोडपेज़ में सभी 256 बाइट मान के लिए वर्ण नहीं होते हैं, और b) डेटा की गलत व्याख्या, Mojibake मेस का उत्पादन करने के बजाय हमेशा
मार्टिन पीटर्स

10

नीचे दिए गए कोड पायथन आउटपुट को विंडोज पर भी UTF-8 के रूप में सांत्वना देंगे।

कंसोल विंडोज 7 पर वर्णों को अच्छी तरह से प्रदर्शित करेगा लेकिन विंडोज एक्सपी पर यह उन्हें अच्छी तरह से प्रदर्शित नहीं करेगा, लेकिन कम से कम यह काम करेगा और सबसे महत्वपूर्ण है कि आपके स्क्रिप्ट से सभी प्लेटफार्मों पर एक सुसंगत आउटपुट होगा। आप आउटपुट को किसी फ़ाइल में पुनर्निर्देशित कर पाएंगे।

विंडोज पर पायथन 2.6 के साथ नीचे कोड का परीक्षण किया गया था।


#!/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"

1
क्या सिर्फ एक अलग कंसोल का उपयोग करके इससे बचने का कोई तरीका है?
एंडोलिथ

@ सोरिन: आप पहले import win32consoleए के बाहर क्यों करते हैं tryऔर बाद में आप सशर्त रूप से ए के अंदर करते हैं try? उस तरह का व्यर्थ (पहला import) नहीं है
0xC0000022L

इसके लायक क्या है, डेविड-सारा होपवुड द्वारा प्रदान किया गया काम (मुझे यह एक भी नहीं मिला क्योंकि मैंने win32 एक्सटेंशन मॉड्यूल को स्थापित करने से परेशान नहीं किया है)
जहमत नहीं उठाई

4
सिस्टम डिफ़ॉल्ट एन्कोडिंग को न बदलें; इसके बजाय अपने यूनिकोड मूल्यों को ठीक करें। डिफ़ॉल्ट एन्कोडिंग को बदलना उन पुस्तकालयों को तोड़ सकता है जो आप पर भरोसा करते हैं, आप जानते हैं, डिफ़ॉल्ट व्यवहार । ऐसा करने के लिए आपको एक मॉड्यूल पुनः लोड करने के लिए मजबूर करने का एक कारण है।
मार्टिज़न पीटर

7

अजगर स्क्रिप्ट को निष्पादित करने से पहले कमांड कोड में इस कोड को दर्ज करें:

chcp 65001 & set PYTHONIOENCODING=utf-8

5

Giampaolo Rodolà के उत्तर की तरह, लेकिन इससे भी अधिक गंदे: मैं वास्तव में, वास्तव में एक लंबे समय (जल्द ही) को एन्कोडिंग के पूरे विषय को समझने का इरादा रखता हूं और वे विंडोझ कंसोल पर कैसे लागू होते हैं,

इस पल के लिए मुझे सिर्फ sthg चाहिए था जिसका मतलब होगा कि मेरा प्रोग्राम CRASH नहीं होगा, और जो मुझे समझ में आया ... और जिसमें बहुत सारे विदेशी मॉड्यूल आयात करना भी शामिल नहीं था (विशेष रूप से मैं Jython का उपयोग कर रहा हूं, इसलिए आधा समय एक Python मॉड्यूल वास्तव में उपलब्ध नहीं है)।

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

एनबी "पीआर" "प्रिंट" की तुलना में टाइप करने के लिए छोटा है (और "सेफप्रिंट" की तुलना में काफी छोटा है) ...!


चतुर, इस मुद्दे के चारों ओर एक त्वरित और गंदा तरीका है। मुझे लगता है कि यह एक आंतरायिक समाधान के लिए बहुत अच्छा है।
JFA

3

पायथन 2 के लिए प्रयास करें:

print unicode(string, 'unicode-escape')

पायथन 3 के लिए प्रयास करें:

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

या जीत-यूनिकोड-कंसोल की कोशिश करें:

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

2

टी एल; डॉ:

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

मैं खुद इस में भाग गया, एक चिकोटी चैट (आईआरसी) बॉट पर काम कर रहा था। (पायथन 2.7 नवीनतम)

मैं जवाब देने के लिए चैट संदेशों को पार्स करना चाहता था ...

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

लेकिन उन्हें मानव-पढ़ने योग्य प्रारूप में कंसोल पर सुरक्षित रूप से प्रिंट करें:

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

इसने बोट फेंकने की UnicodeEncodeError: 'charmap'त्रुटियों को ठीक किया और यूनिकोड वर्णों को प्रतिस्थापित किया ?


2

आपकी समस्या का कारण है नहीं जीत सांत्वना यूनिकोड स्वीकार करने के लिए (यह इस करता है के बाद से मैं डिफ़ॉल्ट रूप से Win2k लगता है) के लिए तैयार नहीं। यह डिफ़ॉल्ट सिस्टम एन्कोडिंग है। इस कोड को आज़माएं और देखें कि यह आपको क्या देता है:

import sys
sys.getdefaultencoding()

अगर यह एससीआई कहता है, तो आपका कारण है;; आपको एक फाइल बनाना है जिसका नाम है sitecustomize.py और इसे python पाथ के नीचे रखना है (मैंने इसे /usr/lib/python2.5/site-packages के तहत रखा है, लेकिन यह अलग है विन - यह निम्न सामग्री के साथ c: \ python \ lib \ site-package या कुछ) है:

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

और शायद आप अपनी फ़ाइलों में एन्कोडिंग निर्दिष्ट करना चाहें:

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

संपादित करें: अधिक जानकारी पायथन पुस्तक में उत्कृष्ट कूदो में पाई जा सकती है


2
setdefaultencoding () मॉड्यूल में dolonger है (मॉड्यूल डॉक्स के अनुसार v2.0)।
जॉन केज

मैं इसे अभी साबित नहीं कर सकता, लेकिन मुझे पता है कि मैंने इस ट्रिक का बाद के संस्करण में उपयोग किया है - 2.5 विंडोज पर।
बार्टोज़ रेडास्कीस्की

6
ठीक है, काफी समय बाद मुझे पता चला है कि: "यह फ़ंक्शन केवल साइट मॉड्यूल कार्यान्वयन द्वारा उपयोग किए जाने का इरादा है और, जहां आवश्यक हो, साइटकस्टम द्वारा। एक बार साइट मॉड्यूल द्वारा उपयोग किए जाने के बाद, यह sys मॉड्यूल के नेमस्पेस से हटा दिया जाता है। "
बार्टोज़ रैडाज़्स्की

4
वास्तव में आप विंडोज़ कंसोल को utf-8 होने के लिए सेट कर सकते हैं। आपको chcp 65001 कहने की आवश्यकता है और यह यूनिकोड होगा।
बार्टोज़ रैदासीस्की

4
इसे बिल्कुल स्पष्ट करने के लिए: डिफ़ॉल्ट एन्कोडिंग को बदलने के लिए यह एक बहुत बुरा विचार है। यह आपके टूटे हुए पैर को फैलाने और चलने के समान है जैसे कि कुछ भी नहीं हुआ, बल्कि डॉक्टर ने हड्डी को ठीक से सेट किया है। यूनिकोड पाठ को संभालने वाले सभी कोड निहित एन्कोडिंग / डिकोडिंग पर निर्भर होने के बजाय लगातार ऐसा करना चाहिए।
मार्टिन पीटर्स

1

JF सेबेस्टियन द्वारा जवाब पर संबंधित की तरह, लेकिन अधिक प्रत्यक्ष।

यदि आपको कंसोल / टर्मिनल पर प्रिंट करते समय यह समस्या हो रही है, तो यह करें:

>set PYTHONIOENCODING=UTF-8

3
set PYTHONIOENCODING=UTF-8अगर सांत्वना cp437 जैसे अलग एन्कोडिंग का उपयोग करता है, तो mojibake हो सकता है । cp65001विभिन्न मुद्दे हैं । यूनिकोड को विंडोज कंसोल में प्रिंट करने के लिए, यूनिकोड एपीआई का उपयोग किया जाना चाहिए ( WriteConsoleW()) जैसा कि मेरे उत्तर में सुझाया गया है, जहां PYTHONIOENCODINGइसका उपयोग केवल उन पात्रों को बदलने के लिए किया जाता है, जिन्हें वर्तमान ओईएम कोड पेज में ?( WriteConsoleW()ऐसे पात्रों के लिए भी काम करता है) प्रतिनिधित्व नहीं किया जा सकता है । PYTHONIOENCODINGयदि आउटपुट किसी फ़ाइल में रीडायरेक्ट किया जाता है, तो इसका उपयोग किया जा सकता है।
jfs

1

पायथन 3.6 विंडोज़ 7: एक पायथन लॉन्च करने का कई तरीका है जिसे आप अजगर कंसोल (जिस पर एक पायथन लोगो है) या विंडोज़ कंसोल (यह उस पर 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ल्यूसिडा कंसोल चुना।


0

जेम्स सुलक ने पूछा,

क्या कोई ऐसा तरीका है जिससे मैं पायथन को स्वचालित रूप से प्रिंट कर सकता हूं? इस स्थिति में असफल होने के बजाय?

अन्य समाधान हमें सलाह देते हैं कि हम विंडोज पर्यावरण को संशोधित करने का प्रयास करें या अजगर की जगह लें print() कार्य । नीचे का उत्तर सुलक के अनुरोध को पूरा करने के करीब आता है।

विंडोज 7 के तहत, पायथन 3.5 को यूनिकोड को प्रिंट किए बिना बनाया जा सकता है UnicodeEncodeError है:

    की जगह:    print(text)
    स्थानापन्न:     print(str(text).encode('utf-8'))

एक अपवाद को फेंकने के बजाय, पायथन अब unprintable यूनिकोड वर्णों को \ xNN हेक्स कोड्स के रूप में प्रदर्शित करता है , जैसे:

  हलामेलो n \ xe2 \ x80 \ x99 \ xc3 \ xa9tait प्लस qu \ xe2 \ x80 \ x99un बिंदु noir

के बजाय

  हलालमो एन'एटिट प्लस क्वून पॉइंट नॉयर

दी गई बात यह है कि उत्तरार्द्ध बेहतर पशु चिकित्सा paribus है , लेकिन अन्यथा पूर्व नैदानिक ​​संदेशों के लिए पूरी तरह से सटीक है। क्योंकि यह यूनिकोड को शाब्दिक बाइट मानों के रूप में प्रदर्शित करता है, पूर्व भी सांकेतिक शब्दों में बदलना / डिकोड समस्याओं का निदान करने में सहायता कर सकता है।

नोट:str() कॉल ऊपर की जरूरत है क्योंकि अन्यथा encode()अजगर संख्या का एक टपल के रूप में एक यूनिकोड वर्ण को अस्वीकार करने का कारण बनता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.