python - कैसे ठीक करें: "यूनिकोडडेकोड त्रुटि: 'ascii' कोडेक बाइट डीकोड नहीं कर सकता"




python-2.7 chinese-locale (8)

as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

इसे कैसे जोड़ेंगे?

कुछ अन्य पायथन आधारित स्थिर ब्लॉग ऐप्स में, चीनी पोस्ट सफलतापूर्वक प्रकाशित किया जा सकता है। इस ऐप के रूप में: http://github.com/vrypan/bucket3 । मेरी साइट http://bc3.brite.biz/ , चीनी पोस्ट सफलतापूर्वक प्रकाशित किया जा सकता है।


tl; डॉ

  • विली नली को डीकोड / एन्कोड न करें
  • मान लें कि आपके तार यूटीएफ -8 एन्कोडेड हैं
  • अपने कोड में जितनी जल्दी हो सके तारों को यूनिकोड स्ट्रिंग में कनवर्ट करने का प्रयास करें

पायथन 2.x - लांग वर्जन

स्रोत को देखे बिना मूल कारण जानना मुश्किल है, इसलिए मुझे आम तौर पर बात करनी होगी।

UnicodeDecodeError: 'ascii' codec can't decode byte सामान्य रूप से तब होता है जब आप एक पायथन 2.x str को परिवर्तित करने का प्रयास करते हैं जिसमें मूल स्ट्रिंग के एन्कोडिंग को निर्दिष्ट किये बिना यूनिकोड स्ट्रिंग में गैर-ASCII शामिल होता है।

संक्षेप में, यूनिकोड तार एक पूरी तरह से अलग प्रकार की पायथन स्ट्रिंग हैं जिसमें कोई एन्कोडिंग नहीं है। वे केवल यूनिकोड पॉइंट कोड रखते हैं और इसलिए पूरे स्पेक्ट्रम से किसी भी यूनिकोड पॉइंट को पकड़ सकते हैं। स्ट्रिंग्स में एन्कोडेड टेक्स्ट, बीआईटी यूटीएफ -8, यूटीएफ -16, आईएसओ -88 9 5-1, जीबीके, बिग 5 इत्यादि शामिल हैंस्ट्रिंग्स को यूनिकोड और यूनिकोड्स को डीकोड किया जाता है , स्ट्रिंग्स को एन्कोड किया जाता है । फ़ाइलें और टेक्स्ट डेटा हमेशा एन्कोडेड तारों में स्थानांतरित होते हैं।

मार्कडाउन मॉड्यूल लेखकों को संभवतः कोड के बाकी हिस्सों के लिए गुणवत्ता गेट के रूप में unicode() (जहां अपवाद फेंक दिया जाता है) का उपयोग करता है - यह एएससीआईआई को परिवर्तित करेगा या मौजूदा यूनिकोड स्ट्रिंग को एक नई यूनिकोड स्ट्रिंग में दोबारा लपेट देगा। मार्कडाउन लेखकों को आने वाली स्ट्रिंग के एन्कोडिंग को नहीं पता हो सकता है, इसलिए मार्कडाउन पर जाने से पहले यूनिकोड स्ट्रिंग्स पर तारों को डीकोड करने के लिए आप पर निर्भर रहेंगे।

स्ट्रिंग के लिए u उपसर्ग का उपयोग करके यूनिकोड तारों को आपके कोड में घोषित किया जा सकता है। उदाहरण के लिए

>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>

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

gotchas

str से यूनिकोड में रूपांतरण तब भी हो सकता है जब आप स्पष्ट रूप से unicode() कॉल नहीं करते हैं।

निम्नलिखित परिदृश्य UnicodeDecodeError अपवाद का कारण UnicodeDecodeError है:

# Explicit conversion without encoding
unicode('€')

# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')

# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'

# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'         

उदाहरण

निम्नलिखित आरेख में, आप देख सकते हैं कि शब्द café को "यूटीएफ -8" या "सीपी 1252" एन्कोडिंग में टर्मिनल प्रकार के आधार पर कैसे एन्कोड किया गया है। दोनों उदाहरणों में, caf सिर्फ नियमित ascii है। यूटीएफ -8 में, दो बाइट्स का उपयोग करके एन्कोड किया गया है। "सीपी 1252" में, 0xE9 है (जो यूनिकोड बिंदु मान भी होता है (यह कोई संयोग नहीं है)। सही decode() का आह्वान किया जाता है और पाइथन यूनिकोड में रूपांतरण सफल होता है:

इस आरेख में, decode() को ascii (जिसे unicode() को एन्कोडिंग के बिना कॉल करने के समान कहा जाता है)। चूंकि ASCII में 0x7F से अधिक बाइट्स नहीं हो सकते हैं, यह एक UnicodeDecodeError अपवाद फेंक देगा:

यूनिकोड सैंडविच

अपने कोड में यूनिकोड सैंडविच बनाने के लिए यह अच्छा अभ्यास है, जहां आप यूनिकोड स्ट्रिंग्स पर सभी आने वाले डेटा को डीकोड करते हैं, यूनिकोड्स के साथ काम करते हैं, फिर रास्ते पर str एस को एन्कोड करते हैं। यह आपको अपने कोड के बीच में तारों के एन्कोडिंग के बारे में चिंता करने से बचाता है।

इनपुट / डिकोड

सोर्स कोड

यदि आपको अपने स्रोत कोड में गैर-ASCII को सेंकने की आवश्यकता है, तो बस u साथ स्ट्रिंग को उपसर्ग करके यूनिकोड स्ट्रिंग बनाएं। उदाहरण के लिए

u'Zürich'

पाइथन को आपके स्रोत कोड को डीकोड करने की अनुमति देने के लिए, आपको अपनी फ़ाइल के वास्तविक एन्कोडिंग से मेल खाने के लिए एक एन्कोडिंग हेडर जोड़ना होगा। उदाहरण के लिए, यदि आपकी फ़ाइल को 'यूटीएफ -8' के रूप में एन्कोड किया गया था, तो आप इसका उपयोग करेंगे:

# encoding: utf-8

यह केवल तब आवश्यक है जब आपके स्रोत कोड में गैर-ASCII न हो।

फ़ाइलें

आम तौर पर फाइल से गैर-ASCII डेटा प्राप्त होता है। io मॉड्यूल एक टेक्स्टवापर प्रदान करता है जो एक दी गई encoding का उपयोग करके आपकी फ़ाइल को फ्लाई पर डीकोड करता है। आपको फ़ाइल के लिए सही एन्कोडिंग का उपयोग करना होगा - इसे आसानी से अनुमानित नहीं किया जा सकता है। उदाहरण के लिए, यूटीएफ -8 फ़ाइल के लिए:

import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
     my_unicode_string = my_file.read() 

my_unicode_string तब my_unicode_string को पास करने के लिए उपयुक्त होगा। यदि read() लाइन से एक UnicodeDecodeError , तो आपने शायद गलत एन्कोडिंग मान का उपयोग किया है।

सीएसवी फाइलें

पायथन 2.7 सीएसवी मॉड्यूल गैर-ASCII वर्णों का समर्थन नहीं करता है 😩। सहायता, हाथ में है, हालांकि, https://pypi.python.org/pypi/backports.csv साथ।

इसे उपरोक्त की तरह प्रयोग करें लेकिन खुली फ़ाइल को पास करें:

from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
    for row in csv.reader(my_file):
        yield row

डेटाबेस

अधिकांश पायथन डेटाबेस ड्राइवर यूनिकोड में डेटा वापस कर सकते हैं, लेकिन आमतौर पर थोड़ा कॉन्फ़िगरेशन की आवश्यकता होती है। SQL क्वेरी के लिए हमेशा यूनिकोड स्ट्रिंग का उपयोग करें।

माई एसक्यूएल

कनेक्शन स्ट्रिंग में जोड़ें:

charset='utf8',
use_unicode=True
PostgreSQL

जोड़ें:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

एचटीटीपी

वेब पृष्ठों को किसी भी एन्कोडिंग में एन्कोड किया जा सकता है। Content-type शीर्षलेख में एन्कोडिंग पर संकेत देने के लिए एक charset फ़ील्ड होना चाहिए। सामग्री को इस मान के विरुद्ध मैन्युअल रूप से डीकोड किया जा सकता है। वैकल्पिक रूप से, Python-Requests response.text में यूनिकोड लौटाता है।

मैन्युअल

यदि आपको मैन्युअल रूप से तारों को डीकोड करना होगा, तो आप बस my_string.decode(encoding) कर सकते हैं, जहां encoding उपयुक्त एन्कोडिंग है। पायथन 2.x समर्थित कोडेक्स यहां दिए गए हैं: मानक एनकोडिंग । दोबारा, यदि आपको UnicodeDecodeError मिलता है तो आपको शायद गलत एन्कोडिंग मिल जाएगी।

सैंडविच का मांस

यूनिकोड्स के साथ काम करें क्योंकि आप सामान्य स्ट्रिंग करेंगे।

उत्पादन

stdout / मुद्रण

print stdout धारा के माध्यम से लिखता है। पायथन स्टडआउट पर एन्कोडर को कॉन्फ़िगर करने का प्रयास करता है ताकि यूनिकोड कंसोल के एन्कोडिंग में एन्कोड किए जाएं। उदाहरण के लिए, यदि एक लिनक्स खोल का locale en_GB.UTF-8 , तो आउटपुट को UTF-8 एन्कोड किया जाएगा। विंडोज़ पर, आप एक 8 बिट कोड पेज तक ही सीमित रहेंगे।

गलत तरीके से कॉन्फ़िगर किया गया कंसोल, जैसे भ्रष्ट लोकेल, अप्रत्याशित प्रिंट त्रुटियों का कारण बन सकता है। PYTHONIOENCODING पर्यावरण परिवर्तक stdout के लिए एन्कोडिंग को मजबूर कर सकते हैं।

फ़ाइलें

इनपुट की तरह, io.open का उपयोग पारदर्शी रूप से एन्कोडेड बाइट स्ट्रिंग में कनवर्ट करने के लिए किया जा सकता है।

डेटाबेस

पढ़ने के लिए एक ही कॉन्फ़िगरेशन यूनिकोड को सीधे लिखा जा सकता है।

पायथन 3

पाइथन 3 में कोई और यूनिकोड पाइथन 2.x के रूप में सक्षम नहीं है, लेकिन नियमित str अब एक यूनिकोड स्ट्रिंग है और पुराना str अब bytes

डिफ़ॉल्ट एन्कोडिंग अब यूटीएफ -8 है, इसलिए यदि आप एन्कोडिंग दिए बिना एक बाइट स्ट्रिंग .decode() पाइथन 3 यूटीएफ -8 एन्कोडिंग का उपयोग करता है। यह शायद 50% लोगों की यूनिकोड समस्याओं को हल करता है।

इसके अलावा, open() डिफ़ॉल्ट रूप से पाठ मोड में काम करता है, इसलिए डीकोडेड str (यूनिकोड वाले) लौटाता है। एन्कोडिंग आपके लोकेल से ली गई है, जो विंडोज़ बॉक्स पर अन * एक्स सिस्टम या 8-बिट कोड पेज जैसे विंडोज -1251 पर यूटीएफ -8 हो जाती है।


एक Django (1.9.10) / पायथन 2.7.5 प्रोजेक्ट में मेरे पास लगातार UnicodeDecodeError अपवाद होते हैं; मुख्य रूप से जब मैं लॉगिंग करने के लिए यूनिकोड तारों को खिलाने का प्रयास करता हूं। मैंने मूल रूप से 8-बिट एसीआई स्ट्रिंग्स को प्रारूपित करने के लिए मनमाने ढंग से ऑब्जेक्ट्स के लिए एक सहायक कार्य किया और किसी भी वर्ण को तालिका में नहीं '?' में बदल दिया। मुझे लगता है कि यह सबसे अच्छा समाधान नहीं है लेकिन चूंकि डिफ़ॉल्ट एन्कोडिंग एएससीआई है (और मैं इसे बदलना नहीं चाहता) यह करेगा:

def encode_for_logging(c, encoding='ascii'):
    if isinstance(c, basestring):
        return c.encode(encoding, 'replace')
    elif isinstance(c, Iterable):
        c_ = []
        for v in c:
            c_.append(encode_for_logging(v, encoding))
        return c_
    else:
        return encode_for_logging(unicode(c))
`


कुछ मामलों में, जब आप अपना डिफ़ॉल्ट एन्कोडिंग ( print sys.getdefaultencoding() ) print sys.getdefaultencoding() , तो यह लौटाता है कि आप ASCII का उपयोग कर रहे हैं। यदि आप यूटीएफ -8 में बदलते हैं, तो यह आपके चर की सामग्री के आधार पर काम नहीं करता है। मुझे एक और रास्ता मिला:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')

मुझे "Pastelera Mallorca" स्ट्रिंग के साथ एक ही समस्या मिली और मैंने हल किया:

unicode("Pastelería Mallorca", 'latin-1')

मुझे सबसे अच्छा लगता है कि हमेशा यूनिकोड में कनवर्ट करना है - लेकिन यह हासिल करना मुश्किल है क्योंकि अभ्यास में आपको हर तर्क और विधि को हर तर्क में परिवर्तित करना होगा और जिस विधि को आपने कभी लिखा है जिसमें स्ट्रिंग प्रसंस्करण के कुछ रूप शामिल हैं।

तो मैं या तो इनपुट से यूनिकोड या बाइट स्ट्रिंग की गारंटी के लिए निम्नलिखित दृष्टिकोण के साथ आया था। संक्षेप में, निम्नलिखित lambdas शामिल करें और उपयोग करें:

# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt) 
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)

उदाहरण:

text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))

इसके बारे में कुछ और तर्क यहां दिया गया है।


मैं निम्न त्रुटि संदेश को हल करने के लिए खोज रहा था:

unicodedecodeerror: 'ascii' कोडेक स्थिति 5454 में बाइट 0xe2 को डीकोड नहीं कर सकता: क्रमिक नहीं श्रेणी में (128)

अंततः मुझे 'एन्कोडिंग' निर्दिष्ट करके तय किया गया:

f = open('../glove/glove.6B.100d.txt', encoding="utf-8")

इच्छा है कि यह आपकी भी मदद कर सके।


यह त्रुटि मुख्य रूप से होती है क्योंकि आपके संदर्भ में एक यूनिकोड स्ट्रिंग की आवश्यकता होती है लेकिन पास किया जाता है केवल एक स्ट्रिंग है। कोड कोड में कनवर्ट करने से पहले यदि स्ट्रिंग पहले से ही यूनिकोड में है, तो आपको किस प्रकार एक टाइपरर मिल जाएगा: डिकोडिंग यूनिकोड समर्थित नहीं है क्योंकि आप यूनिकोड में पहले से ही एक स्ट्रिंग में कनवर्ट करने की कोशिश कर रहे हैं। आप इसे पहले से कनवर्ट करने से पहले जांचें नीचे:

        if isinstance(input_string, str):
            input_string = unicode(input_string, 'utf-8')

उपरोक्त को जोड़कर, उपर्युक्त असमर्थित वर्णों को हटा नहीं देता है। यह सिर्फ प्रकार बदलता है लेकिन गैर ascii अभी भी बनी हुई है। पात्रों को हटाने के लिए नीचे का उपयोग करें,

        if isinstance(input_string, str):
            input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.
        elif isinstance(input_string, unicode):
            input_string = input_string.encode('ascii', 'ignore')

संक्षेप में, पायथन 2 में उचित यूनिकोड हैंडलिंग सुनिश्चित करने के लिए:

  • फ़ाइलों को पढ़ने / लिखने के लिए io.open उपयोग करें
  • from __future__ import unicode_literals उपयोग करें
  • यूनिकोड का उपयोग करने के लिए अन्य डेटा इनपुट / आउटपुट (उदाहरण के लिए, डेटाबेस, नेटवर्क) को कॉन्फ़िगर करें
  • यदि आप आउटपुट को utf-8 में कॉन्फ़िगर नहीं कर सकते हैं, तो उनके आउटपुट को उनके लिए print(text.encode('ascii', 'replace').decode())

स्पष्टीकरण के लिए, @Alastair McCormack का विस्तृत उत्तर देखें ।





chinese-locale