tl; डॉआर / क्विक फिक्स
- विकोडी / एनोडी को डीकोड / एनकोड न करें
- मान लें कि आपके तार UTF-8 एन्कोडेड नहीं हैं
- अपने कोड में जितनी जल्दी हो सके स्ट्रिंग्स को यूनिकोड स्ट्रिंग्स में बदलने का प्रयास करें
- अपने स्थान को ठीक करें: पायथन 3.6 में यूनिकोडड्रेसराइड को कैसे हल करें?
- त्वरित
reload
हैक का उपयोग करने के लिए परीक्षा मत करो
पायथन 2.x में यूनिकोड ज़ेन - लॉन्ग वर्जन
स्रोत को देखे बिना मूल कारण जानना मुश्किल है, इसलिए मुझे आम तौर पर बोलना होगा।
UnicodeDecodeError: 'ascii' codec can't decode byte
आम तौर पर तब होता है जब आप एक पायथन 2.x को परिवर्तित करने का प्रयास करते हैं str
जिसमें मूल स्ट्रिंग के एन्कोडिंग को निर्दिष्ट किए बिना एक यूनिकोड स्ट्रिंग में गैर-एएससीआईआई होता है।
संक्षेप में, यूनिकोड स्ट्रिंग्स एक पूरी तरह से अलग प्रकार का पायथन स्ट्रिंग है जिसमें कोई एन्कोडिंग नहीं होती है। वे केवल यूनिकोड बिंदु कोड रखते हैं और इसलिए पूरे स्पेक्ट्रम से किसी भी यूनिकोड बिंदु को पकड़ सकते हैं। स्ट्रिंग्स में एन्कोडेड टेक्स्ट होता है, इसके अलावा UTF-8, UTF-16, ISO-8895-1, GBK, Big5 आदि स्ट्रिंग्स को यूनिकोड में डिकोड किया जाता है और यूनिकोड को स्ट्रिंग्स में एनकोड किया जाता है । फ़ाइलें और पाठ डेटा हमेशा एन्कोडेड स्ट्रिंग्स में स्थानांतरित किए जाते हैं।
मार्कडाउन मॉड्यूल लेखक संभवत: unicode()
कोड के बाकी हिस्सों के लिए गुणवत्ता गेट के रूप में (जहां अपवाद को फेंक दिया गया है) का उपयोग करते हैं - यह एएससीआईआई या मौजूदा यूनिकोड के तारों को नए यूनिकोड स्ट्रिंग में बदल देगा। मार्कडाउन लेखक आने वाली स्ट्रिंग के एन्कोडिंग को नहीं जान सकते हैं, इसलिए मार्कडाउन में जाने से पहले यूनिकोड के तारों को डिकोड करने के लिए आप पर भरोसा करेंगे।
आपके कोड में यूनिकोड स्ट्रिंग्स को u
उपसर्ग का उपयोग करके स्ट्रिंग्स में घोषित किया जा सकता है । उदाहरण के लिए
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
यूनिकोड के तार फाइल, डेटाबेस और नेटवर्क मॉड्यूल से भी आ सकते हैं। जब ऐसा होता है, तो आपको एन्कोडिंग के बारे में चिंता करने की आवश्यकता नहीं है।
gotchas
str
यूनिकोड से रूपांतरण तब भी हो सकता है जब आप स्पष्ट रूप से कॉल नहीं करते हैं unicode()
।
निम्नलिखित परिदृश्य 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é
टर्मिनल प्रकार के आधार पर शब्द "UTF-8" या "Cp1252" एन्कोडिंग में कैसे एन्कोड किया गया है। दोनों उदाहरणों में, caf
बस नियमित रूप से एससीआई है। UTF-8 में, é
दो बाइट्स का उपयोग करके एन्कोड किया गया है। "Cp1252" में, é 0xE9 है (जो यूनिकोड बिंदु मान होने के लिए भी होता है (यह कोई संयोग नहीं है))। सही decode()
को लागू किया जाता है और पायथन यूनिकोड में रूपांतरण सफल होता है:
इस आरेख में, के decode()
साथ कहा जाता है ascii
(जो unicode()
किसी एन्कोडिंग के बिना कॉल करने के समान है )। ASCII में बाइट्स से अधिक नहीं हो सकता है 0x7F
, यह एक UnicodeDecodeError
अपवाद फेंक देगा :
यूनिकोड सैंडविच
अपने कोड में एक यूनिकोड सैंडविच बनाना अच्छा है, जहाँ आप यूनिकोड स्ट्रिंग्स के लिए आने वाले सभी डेटा को डिकोड करते हैं, यूनिकोड के साथ काम करते हैं, फिर str
बाहर जाने के रास्ते पर एनकोड करते हैं। यह आपको अपने कोड के बीच में तार के एन्कोडिंग के बारे में चिंता करने से बचाता है।
इनपुट / डिकोड
सोर्स कोड
यदि आपको अपने स्रोत कोड में गैर-एएससीआईआई सेंकना करने की आवश्यकता है, तो बस स्ट्रिंग को उपसर्ग करके यूनिकोड तार बनाएं u
। उदाहरण के लिए
u'Zürich'
पायथन को अपने स्रोत कोड को डिकोड करने की अनुमति देने के लिए, आपको अपनी फ़ाइल के वास्तविक एन्कोडिंग से मिलान करने के लिए एन्कोडिंग हेडर जोड़ना होगा। उदाहरण के लिए, यदि आपकी फ़ाइल 'UTF-8' के रूप में एन्कोडेड थी, तो आप उपयोग करेंगे:
# encoding: utf-8
यह तभी आवश्यक है जब आपके स्रोत कोड में गैर-एएससीआईआई हो ।
फ़ाइलें
आमतौर पर गैर-एएससीआईआई डेटा एक फ़ाइल से प्राप्त होता है। io
मॉड्यूल एक TextWrapper कि तेज़ी से अपने फ़ाइल डीकोड, किसी दिए गए का उपयोग कर प्रदान करता है encoding
। आपको फ़ाइल के लिए सही एन्कोडिंग का उपयोग करना चाहिए - यह आसानी से अनुमान नहीं लगाया जा सकता है। उदाहरण के लिए, UTF-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
तब मार्कडाउन में जाने के लिए उपयुक्त होगा। एक तो UnicodeDecodeError
से read()
लाइन, तो आप शायद गलत एन्कोडिंग मूल्य का उपयोग किया है।
CSV फ़ाइलें
पायथन 2.7 सीएसवी मॉड्यूल गैर-एएससीआईआई CS का समर्थन नहीं करता है। हालांकि, मदद 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
उदाहरण के लिए
>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL
जोड़ें:
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
एचटीटीपी
वेब पेजों को केवल किसी भी एन्कोडिंग के बारे में एन्कोड किया जा सकता है। Content-type
हैडर एक को शामिल करना चाहिए charset
एन्कोडिंग में संकेत करने के लिए क्षेत्र। तब सामग्री को इस मान के विरुद्ध मैन्युअल रूप से डिकोड किया जा सकता है। वैकल्पिक रूप से, पायथन-रिक्वेस्ट्स में यूनिकोड की वापसी होती है response.text
।
मैन्युअल
यदि आपको स्ट्रिंग्स को मैन्युअल रूप से डीकोड करना होगा, तो आप बस कर सकते हैं my_string.decode(encoding)
, जहां encoding
उपयुक्त एन्कोडिंग है। पायथन 2.x समर्थित कोडेक्स यहां दिए गए हैं: मानक एनकोडिंग । फिर, यदि आप प्राप्त करते हैं UnicodeDecodeError
तो आपको शायद गलत एन्कोडिंग मिल गई है।
सैंडविच का मांस
यूनिकोड के साथ काम करें क्योंकि आप सामान्य स्ट्रैस करेंगे।
उत्पादन
स्टडआउट / प्रिंटिंग
print
स्टडआउट स्ट्रीम के माध्यम से लिखते हैं। पायथन ने एक एनकोडर को stdout पर कॉन्फ़िगर करने की कोशिश की ताकि यूनिकोड कंसोल के एन्कोडिंग में एन्कोड हो जाए। उदाहरण के लिए, यदि लिनक्स शेल locale
है en_GB.UTF-8
, तो आउटपुट को इनकोड किया जाएगा UTF-8
। विंडोज पर, आप एक 8bit कोड पेज तक सीमित रहेंगे।
एक गलत तरीके से कॉन्फ़िगर किया गया कंसोल, जैसे भ्रष्ट स्थान, अप्रत्याशित प्रिंट त्रुटियों को जन्म दे सकता है। PYTHONIOENCODING
परिवेश चर stdout के लिए एन्कोडिंग को बाध्य कर सकता है।
फ़ाइलें
इनपुट की तरह, io.open
यूनिकोड को पारदर्शी रूप से एन्कोडेड बाइट स्ट्रिंग्स में बदलने के लिए उपयोग किया जा सकता है।
डेटाबेस
पढ़ने के लिए एक ही विन्यास यूनिकोड को सीधे लिखने की अनुमति देगा।
अजगर ३
पायथन 3 पायथन 2.x की तुलना में अधिक यूनिकोड सक्षम नहीं है, हालांकि यह विषय पर थोड़ा कम भ्रमित है। जैसे कि नियमित str
अब एक यूनिकोड स्ट्रिंग है और पुराना str
अब है bytes
।
डिफ़ॉल्ट एन्कोडिंग UTF-8 है, इसलिए यदि आप .decode()
एन्कोडिंग दिए बिना एक बाइट स्ट्रिंग करते हैं, तो पायथन 3 UTF-8 एन्कोडिंग का उपयोग करता है। यह शायद 50% लोगों की यूनिकोड समस्याओं को ठीक करता है।
इसके अलावा, open()
डिफ़ॉल्ट रूप से पाठ मोड में काम करता है, इसलिए रिटर्न डिकोडेड str
(यूनिकोड वाले)। एन्कोडिंग आपके लोकेल से ली गई है, जो Un * x सिस्टम पर UTF-8 या विंडोज बॉक्स पर एक 8-बिट कोड पेज, जैसे कि विंडोज़ -1251 है।
आप का उपयोग क्यों नहीं करना चाहिए sys.setdefaultencoding('utf8')
यह एक बुरा हैक है (इसका एक कारण है जिसका आपको उपयोग reload
करना होगा) जो केवल समस्याओं का सामना करेगा और आपके 3. Python में प्रवास को बाधित करेगा। समस्या को समझें, मूल कारण को ठीक करें और यूनिकोड ज़ेन का आनंद लें। देखें कि हमें py स्क्रिप्ट में sys.setdefaultencoding ("utf-8") का उपयोग क्यों नहीं करना चाहिए? अधिक जानकारी के लिए