अजगर - 'अस्सी' कोडक बाइट को डिकोड नहीं कर सकता है


119

मैं वास्तव में उलझन में हूँ। मैंने सांकेतिक शब्दों में बदलना की कोशिश की, लेकिन त्रुटि कहा can't decode...

>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

मुझे पता है कि स्ट्रिंग पर "यू" उपसर्ग के साथ त्रुटि से कैसे बचें। मैं सोच रहा था कि जब एनकोड कहा जाता है तो त्रुटि "डिकोड नहीं हो सकती" क्यों है। अजगर हुड के नीचे क्या कर रहा है?

जवाबों:


167
"你好".encode('utf-8')

encodeएक यूनिकोड ऑब्जेक्ट को ऑब्जेक्ट में कनवर्ट करता है string। लेकिन यहां आपने इसे एक stringवस्तु पर लागू किया है (क्योंकि आपके पास यू नहीं है)। तो अजगर को पहले stringएक unicodeवस्तु में बदलना होगा । तो यह के बराबर है

"你好".decode().encode('utf-8')

लेकिन डिकोड विफल रहता है क्योंकि स्ट्रिंग मान्य नहीं है। इसलिए आपको डिकोड न कर पाने की शिकायत मिलती है।


50
तो समाधान क्या है? खासकर अगर मेरे पास एक स्ट्रिंग शाब्दिक नहीं है, तो मेरे पास एक स्ट्रिंग ऑब्जेक्ट है।
जॉन टाइरसन

2
@JonTirsen, आपको एक स्ट्रिंग ऑब्जेक्ट एन्कोडिंग नहीं होना चाहिए। एक स्ट्रिंग ऑब्जेक्ट पहले से एन्कोडेड है। यदि आपको एन्कोडिंग बदलने की आवश्यकता है, तो आपको इसे एक यूनिकोड स्ट्रिंग में डिकोड करने की आवश्यकता है और फिर इसे वांछित एन्कोडिंग के रूप में एन्कोड करें।
विंस्टन इर्वर्ट

20
इसलिए इसे ऊपर से स्पष्ट रूप से "你好".decode('utf-8').encode('utf-8')
बताने के लिए

5
@WinstonEwert मुझे लगता है कि मैं भ्रमित था। एन्कोडिंग व्यवसाय मुझे हमेशा उलझन में छोड़ देता है। मुझे लगता है कि मेरी उलझन मेरी अपनी समस्या से यह जानने की नहीं थी कि क्या इनपुट एक स्ट्रिंग या यूनिकोड स्ट्रिंग है और इसमें क्या एन्कोडिंग हो सकती है।
डेनिसोनीचसौर

@deinonychusaur, हाँ ... मुझे लगता है कि मिलता है।
विंस्टन इर्वर्ट

53

हमेशा यूनिकोड से बाइट्स तक एनकोड करें
इस दिशा में, आपको एन्कोडिंग का चयन करना है

>>> u"你好".encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print _
你好

दूसरा तरीका बाइट्स से यूनिकोड तक डिकोड करना है।
इस दिशा में, आपको यह जानना होगा कि एन्कोडिंग क्या है

>>> bytes = '\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print bytes
你好
>>> bytes.decode('utf-8')
u'\u4f60\u597d'
>>> print _
你好

इस बिंदु पर पर्याप्त जोर नहीं दिया जा सकता है। यदि आप यूनिकोड "व्हेक-ए-मोल" खेलने से बचना चाहते हैं, तो यह समझना महत्वपूर्ण है कि डेटा स्तर पर क्या हो रहा है। यहाँ यह एक और तरीका बताया गया है:

  • एक यूनिकोड ऑब्जेक्ट पहले से ही डीकोड किया गया है, आप कभी भी decodeउस पर कॉल नहीं करना चाहते हैं ।
  • एक बाइटस्ट्रिंग ऑब्जेक्ट पहले से एन्कोडेड है, आप कभी भी encodeउस पर कॉल नहीं करना चाहते हैं ।

अब, .encodeएक बाइट स्ट्रिंग पर देखने पर, पायथन 2 पहले इसे स्पष्ट रूप से पाठ (एक unicodeवस्तु) में बदलने की कोशिश करता है । इसी तरह, .decodeएक यूनिकोड स्ट्रिंग पर देखने पर, पायथन 2 स्पष्ट रूप से इसे बाइट्स (एक strवस्तु) में बदलने की कोशिश करता है ।

ये निहितार्थ हैं कि जब आप कॉल करें तो आप क्यों प्राप्त कर सकते हैं । ऐसा इसलिए है क्योंकि एन्कोडिंग आमतौर पर प्रकार के एक पैरामीटर को स्वीकार करता है ; जब एक पैरामीटर प्राप्त होता है , तो एक एन्कोडिंग के साथ इसे फिर से एन्कोडिंग करने से पहले एक ऑब्जेक्ट में एक अंतर्निहित डिकोडिंग होता है । इस रूपांतरण एक डिफ़ॉल्ट 'ascii' विकोडक चुनता , एक एनकोडर के अंदर आप डिकोडिंग त्रुटि है।UnicodeDecodeErrorencodeunicodestrunicode

वास्तव में, पायथन 3 में विधियाँ str.decodeऔर bytes.encodeमौजूद नहीं हैं। इस आम भ्रम से बचने के लिए उनका निष्कासन [विवादास्पद] प्रयास था।

... या जो भी कोडिंग sys.getdefaultencoding()उल्लेख करता है; आमतौर पर यह 'अस्सी' है


तो क्या आपका मतलब है कि पायथन एन्कोडिंग से पहले बाइटस्ट्रिंग को डिकोड करता है?
थोसलिन

@thoslin वास्तव में, मैंने और विवरण जोड़ा।
दोपहर

_ क्या है, और आपके प्रिंट स्टेटमेंट में कोष्ठक क्यों गायब हैं?
NoBugs

1
@NoBugs 1. REPL में, _पिछले मान को संदर्भित करता है 2. क्योंकि यह एक अजगर-2. x प्रश्न है।
विम

40

आप यह कोशिश कर सकते हैं

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

या

आप निम्न का भी प्रयास कर सकते हैं

अपने .py फ़ाइल के शीर्ष पर निम्न पंक्ति जोड़ें।

# -*- coding: utf-8 -*- 

8

यदि आप पायथन <3 का उपयोग कर रहे हैं, तो आपको दुभाषिया को यह बताने की आवश्यकता होगी कि आपका स्ट्रिंग शाब्दिक यूनिकोड है जो इसे उपसर्ग कर रहा हैu :

Python 2.7.2 (default, Jan 14 2012, 23:14:09) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "你好".encode("utf8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
>>> u"你好".encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'

आगे पढ़ें : यूनिकोड विधिपत्र


4
यदि आप एक स्ट्रिंग एन्कोडिंग कर रहे हैं, तो यह डिकोड त्रुटि क्यों है?
MxLDevs

3

आप u"你好".encode('utf8')एक यूनिकोड स्ट्रिंग को एनकोड करने के लिए उपयोग करते हैं । लेकिन अगर आप प्रतिनिधित्व करना चाहते हैं "你好", तो आपको इसे डिकोड करना चाहिए। बिलकुल इसके जैसा:

"你好".decode("utf8")

आपको वही मिलेगा जो आप चाहते हैं। शायद आपको सांकेतिक शब्दों में बदलना और डिकोड करना चाहिए।


3

यदि आप यूनिकोड के साथ काम कर रहे हैं, तो कभी-कभी इसके बजाय encode('utf-8'), आप विशेष वर्णों को अनदेखा करने का भी प्रयास कर सकते हैं, जैसे

"你好".encode('ascii','ignore')

या जैसा something.decode('unicode_escape').encode('ascii','ignore')कि यहाँ सुझाया गया है

इस उदाहरण में विशेष रूप से उपयोगी नहीं है, लेकिन अन्य परिदृश्यों में बेहतर काम कर सकता है जब कुछ विशेष वर्णों को परिवर्तित करना संभव नहीं है।

वैकल्पिक रूप से आप किसी विशेष वर्ण का उपयोग करने परreplace() विचार कर सकते हैं ।


1

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

locale charmapशेल से कॉल करें (अजगर दुभाषिया नहीं) और आपको देखना चाहिए

[user@host dir] $ locale charmap
UTF-8
[user@host dir] $ 

यदि यह मामला नहीं है, और आप कुछ और देखते हैं, जैसे

[user@host dir] $ locale charmap
ANSI_X3.4-1968
[user@host dir] $ 

पायथन होगा (कम से कम कुछ मामलों में जैसे मेरा) शेल के एन्कोडिंग को विरासत में मिला है और यूनिकोड वर्णों को प्रिंट नहीं कर पाएगा (कुछ? सभी?)। पायथन की अपनी डिफ़ॉल्ट एन्कोडिंग जिसे आप देखते हैं और उसके माध्यम से नियंत्रित करते हैं sys.getdefaultencoding()औरsys.setdefaultencoding() इस मामले पर ध्यान नहीं दिया है।

यदि आप पाते हैं कि आपको यह समस्या है, तो आप इसे ठीक कर सकते हैं

[user@host dir] $ export LC_CTYPE="en_EN.UTF-8"
[user@host dir] $ locale charmap
UTF-8
[user@host dir] $ 

(या वैकल्पिक रूप से जो भी आप चाहते हैं कि आप en_EN के बजाय कीमैप चुनें।) इसे संपादित करने के लिए आप /etc/locale.conf(या जो भी फ़ाइल आपके सिस्टम में स्थानीय परिभाषा को नियंत्रित करता है) को संपादित कर सकते हैं ।

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