दिलचस्प पोस्ट
कैसे कैनवास में छवि जोड़ने के लिए एक क्लासपाथ क्या है? यूआईपीकर देखें और एक बटन में कार्य पत्र – कैसे? असफल मान्यकरण या अमान्य डुप्लिकेट के लिए खाली HTTP स्थिति कोड क्या स्ट्रीमरीडर का निपटारा धारा बंद कर देता है? पारदर्शी तीर / त्रिकोण जावा में सापेक्ष पथ के साथ खुले संसाधन पूर्णांक आधारित पावर फ़ंक्शन पॉ (एएनटी, इंट) को लागू करने का सबसे कारगर तरीका प्रीपेड डबल कॉलन "::" का क्या अर्थ है? पायथन __str__ बनाम __unicode__ Mongoose में पॉप्यूल किए जाने के बाद पूछताछ `Im2col` और` col2im` के कुशल कार्यान्वयन तिथि सीमा से दिन उत्पन्न करें जावास्क्रिप्ट रेगेक्स में एक मनमानी समूहों की संख्या कैसे कैप्चर करें? एसएसआईएस 2012 पैकेज को निष्पादित करना जिसमें बाह्य अनुप्रयोग से स्क्रिप्ट घटक हैं

विंडोज सीएमडी एन्कोडिंग परिवर्तन पायथन दुर्घटना का कारण बनता है

सबसे पहले मैं विंडोज़ सीएमडी एन्कोडिंग को यूटीएफ -8 में बदलता हूं और पायथन इंटरप्रेटर को चलाता हूं:

chcp 65001 python 

फिर मैं इसके अंदर एक यूनिकोड स्टिंग को प्रिंट करने की कोशिश करता हूं और जब मैं यह अजगर एक विशेष तरीके से क्रैश करता हूं (मुझे एक ही विंडो में सीएमडी प्रॉम्प्ट मिलता है)।

 >>> import sys >>> print u'ëèæîð'.encode(sys.stdin.encoding) 

कोई भी विचार क्यों ऐसा होता है और इसे कैसे काम करना है?

UPD : sys.stdin.encoding रिटर्न 'cp65001'

UPD2 : यह सिर्फ मेरे पास आया था कि यह मुद्दा इस तथ्य से जुड़ा हो सकता है कि यूटीएफ -8 बहु-बाइट कैरेक्टर सेट का उपयोग करता है (केसीवीयू ने उस पर एक अच्छा मुद्दा बनाया) मैंने 'windows-1250' के साथ पूरे उदाहरण को चलाने की कोशिश की और 'éeï?' मिला। Windows-1250 सिंगल-वर्ण सेट का उपयोग करता है इसलिए यह उन वर्णों के लिए काम करता है जो इसे समझते हैं। हालांकि मुझे अब भी पता नहीं है कि 'यूटीएफ -8' का काम कैसे करें I

UPD3 : ओह, मुझे पता चला कि यह एक ज्ञात पायथन बग है । मुझे लगता है कि क्या होता है यह है कि पायथन सीडीडी एन्कोडिंग को 'सीएसटीसीआईएनएसीएनसीडीएडी के रूप में सीपी65001 की कॉपी करता है और इसे सभी इनपुट पर लागू करने की कोशिश करता है। चूंकि यह 'cp65001' समझने में विफल रहता है, इसलिए यह गैर-आस्की वर्णों वाले किसी भी इनपुट पर क्रैश हो जाता है।

वेब के समाधान से एकत्रित समाधान "विंडोज सीएमडी एन्कोडिंग परिवर्तन पायथन दुर्घटना का कारण बनता है"

encodings\aliases.py को बदलने के बिना यूटीएफ -8 के उपनाम cp65001 के बारे में यहां बताया गया है encodings\aliases.py :

 import codecs codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) 

( cp65001 , http://bugs.python.org/issue6058#msg97731 पर यूटीएफ -8 के समान नहीं होने वाली cp65001 बारे में मूर्खता के बारे में कोई ध्यान नहीं देते। इसका उद्देश्य एक ही है, भले ही माइक्रोसॉफ्ट के कोडेक में कुछ नाबालिग कीड़े।)

यहां कुछ कोड है (जो Tahoe-LAFS के लिए लिखा गया है, tahoe-lafs.org) जो chcp कोड पेज की परवाह किए बिना कंसोल आउटपुट काम करता है, और यूनिकोड कमांड लाइन आर्ग्यूमेंट भी पढ़ता है। इस समाधान के पीछे के विचार के लिए माइकल कपलान को श्रेय। यदि stdout या stderr को पुनः निर्देशित किया जाता है, तो यह यूटीएफ -8 आउटपुट करेगा। यदि आप बाइट ऑर्डर मार्क चाहते हैं, तो आपको इसे स्पष्ट रूप से लिखना होगा।

[संपादित करें: यह संस्करण WriteConsoleW रनटाइम लाइब्रेरी में _O_U8TEXT ध्वज के बजाए WriteConsoleW का उपयोग करता है, जो कि छोटी गाड़ी है WriteConsoleW एमएस प्रलेखन के सापेक्ष WriteConsoleW भी है, लेकिन कम है।]

 import sys if sys.platform == "win32": import codecs from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID original_stderr = sys.stderr # If any exception occurs in this code, we'll probably try to print it on stderr, # which makes for frustrating debugging if stderr is directed to our wrapper. # So be paranoid about catching errors and reporting them to original_stderr, # so that we can at least see them. def _complain(message): print >>original_stderr, message if isinstance(message, str) else repr(message) # Work around <http://bugs.python.org/issue6058>. codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) # Make Unicode console output work independently of the current code page. # This also fixes <http://bugs.python.org/issue1602>. # Credit to Michael Kaplan <http://www.siao2.com/2010/04/07/9989346.aspx> # and TZOmegaTZIOY # <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. try: # <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdout_fileno = None old_stderr_fileno = None if hasattr(sys.stdout, 'fileno'): old_stdout_fileno = sys.stdout.fileno() if hasattr(sys.stderr, 'fileno'): old_stderr_fileno = sys.stderr.fileno() STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: # BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars, # LPDWORD lpCharsWritten, LPVOID lpReserved); WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(("WriteConsoleW", windll.kernel32)) class UnicodeOutput: def __init__(self, hConsole, stream, fileno, name): self._hConsole = hConsole self._stream = stream self._fileno = fileno self.closed = False self.softspace = False self.mode = 'w' self.encoding = 'utf-8' self.name = name self.flush() def isatty(self): return False def close(self): # don't really close the handle, that would only cause problems self.closed = True def fileno(self): return self._fileno def flush(self): if self._hConsole is None: try: self._stream.flush() except Exception as e: _complain("%s.flush: %r from %r" % (self.name, e, self._stream)) raise def write(self, text): try: if self._hConsole is None: if isinstance(text, unicode): text = text.encode('utf-8') self._stream.write(text) else: if not isinstance(text, unicode): text = str(text).decode('utf-8') remaining = len(text) while remaining: n = DWORD(0) # There is a shorter-than-documented limitation on the # length of the string passed to WriteConsoleW (see # <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232>. retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None) if retval == 0 or n.value == 0: raise IOError("WriteConsoleW returned %r, n.value = %r" % (retval, n.value)) remaining -= n.value if not remaining: break text = text[n.value:] except Exception as e: _complain("%s.write: %r" % (self.name, e)) raise def writelines(self, lines): try: for line in lines: self.write(line) except Exception as e: _complain("%s.writelines: %r" % (self.name, e)) raise if real_stdout: sys.stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO, '<Unicode console stdout>') else: sys.stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>') if real_stderr: sys.stderr = UnicodeOutput(hStderr, None, STDERR_FILENO, '<Unicode console stderr>') else: sys.stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>') except Exception as e: _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e,)) # While we're at it, let's unmangle the command-line arguments: # This works around <http://bugs.python.org/issue2128>. GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(("CommandLineToArgvW", windll.shell32)) argc = c_int(0) argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) argv = [argv_unicode[i].encode('utf-8') for i in xrange(0, argc.value)] if not hasattr(sys, 'frozen'): # If this is an executable produced by py2exe or bbfreeze, then it will # have been invoked directly. Otherwise, unicode_argv[0] is the Python # interpreter, so skip that. argv = argv[1:] # Also skip option arguments to the Python interpreter. while len(argv) > 0: arg = argv[0] if not arg.startswith(u"-") or arg == u"-": break argv = argv[1:] if arg == u'-m': # sys.argv[0] should really be the absolute path of the module source, # but never mind break if arg == u'-c': argv[0] = u'-c' break # if you like: sys.argv = argv 

अंत में, यह संभव है कि दीवाना वीजा सेन्स मोनो का इस्तेमाल करना ΤΖΩΤΖΙΟΥ की इच्छा है, जिसे मैं सहमत हूं कंसोल के लिए एक उत्कृष्ट फ़ॉन्ट है।

आप फ़ॉन्ट आवश्यकताओं के बारे में जानकारी पा सकते हैं और खिड़कियों के कंसोल के लिए नए फोंट को कैसे जोड़ सकते हैं 'कमांड विंडो में उपलब्ध फ़ॉन्ट्स के लिए आवश्यक मानदंड' में Microsoft KB

लेकिन मूल रूप से, विस्टा (शायद भी Win7) पर:

  • HKEY_LOCAL_MACHINE_SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont अंतर्गत, "0" "DejaVu Sans Mono" ;
  • HKEY_CURRENT_USER\Console तहत प्रत्येक उपकुंजियों के लिए, "FaceName" को "DejaVu Sans Mono" सेट HKEY_CURRENT_USER\Console

एक्सपी पर, थ्रेड 'कमांड प्रॉम्प्ट फोन्टिंग बदल रहा है?' लॉकरग्नोम मंचों में

PYTHONIOENCODING सिस्टम चर सेट करें:

 > chcp 65001 > set PYTHONIOENCODING=utf-8 > python example.py Encoding is utf-8 

example.py का स्रोत सरल है:

 import sys print "Encoding is", sys.stdin.encoding 

मुझे यह परेशान करने वाला मुद्दा भी था, और मुझे लिनक्स के रूप में एमएस विंडोज में अपनी यूनिकोड-स्किप लिपियों को चलाने में सक्षम न होने से नफरत है। तो, मैं एक वैकल्पिक हल के साथ आया था।

इस स्क्रिप्ट को लें (कहते हैं, अपनी साइट-पैकेज में uniconsole.py या जो भी):

 import sys, os if sys.platform == "win32": class UniStream(object): __slots__= ("fileno", "softspace",) def __init__(self, fileobject): self.fileno = fileobject.fileno() self.softspace = False def write(self, text): os.write(self.fileno, text.encode("utf_8") if isinstance(text, unicode) else text) sys.stdout = UniStream(sys.stdout) sys.stderr = UniStream(sys.stderr) 

यह अजगर बग के आसपास काम करता है (या Win32 यूनिकोड कंसोल बग, जो भी)। फिर मैंने सभी संबंधित लिपियों में जोड़ा:

 try: import uniconsole except ImportError: sys.exc_clear() # could be just pass, of course else: del uniconsole # reduce pollution, not needed anymore 

आखिरकार, मैं सिर्फ मेरी स्क्रिप्ट चलाता हूँ जैसा कंसोल में आवश्यक होता है जहां chcp 65001 चलाया जाता है और फॉन्ट Lucida Console (मैं कैसे चाहता हूं कि DejaVu Sans Mono इसके बजाय इस्तेमाल किया जा सकता है … लेकिन रजिस्ट्री को हैकिंग और इसे एक बिटमैप फ़ॉन्ट में कंसोल फ़ॉन्ट के रूप में चुनने के लिए चुना गया।)

यह एक त्वरित और गंदे stdout और stderr प्रतिस्थापन है, और यह भी किसी भी raw_input संबंधित बग को संभाल नहीं करता है (जाहिर है, क्योंकि यह बिल्कुल sys.stdin को स्पर्श नहीं करता है)। और, वैसे, मैंने मानक उदारीकरण के encodings\aliases.py फ़ाइल में utf_8 लिए utf_8 उपनाम जोड़ दिया है।

इसका कारण यह है कि सीएमडी का "कोड पृष्ठ" सिस्टम के "एमबीसीएस" के लिए अलग है। यद्यपि आपने "कोड पृष्ठ" को बदल दिया है, अजगर (वास्तव में, खिड़कियां) अभी भी लगता है कि आपके "एमबीसीएस" में बदलाव नहीं होता है

कुछ टिप्पणियां: आप शायद .code और। यहाँ आपके उदाहरण का मेरा भाग है I

 C:\>chcp 65001 Active code page: 65001 C:\>\python25\python ... >>> import sys >>> sys.stdin.encoding 'cp65001' >>> s=u'\u0065\u0066' >>> s u'ef' >>> s.encode(sys.stdin.encoding) Traceback (most recent call last): File "<stdin>", line 1, in <module> LookupError: unknown encoding: cp65001 >>> 

निष्कर्ष – cp65001 अजगर के लिए एक ज्ञात एन्कोडिंग नहीं है 'UTF-16' या कुछ इसी तरह की कोशिश करो

क्या आप पायथन को यूटीएफ -8 में सांकेतिक शब्दों में लिखना चाहते हैं?

 >>>print u'ëèæîð'.encode('utf-8') ëèæîð 

पायथन यूटीएफ -8 के रूप में सीपी65001 पहचान नहीं करेगा