पायथन में यूनिकोड () और एनकोड () कार्यों का उपयोग


83

मुझे पथ चर के एन्कोडिंग और इसे SQLite डेटाबेस में डालने की समस्या है। मैंने इसे एनकोड ("utf-8") फ़ंक्शन के साथ हल करने की कोशिश की, जिसने मदद नहीं की। फिर मैंने यूनिकोड () फ़ंक्शन का उपयोग किया जो मुझे यूनिकोड टाइप करता है

print type(path)                  # <type 'unicode'>
path = path.replace("one", "two") # <type 'str'>
path = path.encode("utf-8")       # <type 'str'> strange
path = unicode(path)              # <type 'unicode'>

अंत में मैं प्राप्त यूनिकोड प्रकार है, लेकिन मैं अब भी वही त्रुटि जो मौजूद था जब के प्रकार है पथ चर था str

sqlite3.ProgrammingError: जब तक आप एक text_factory का उपयोग नहीं करते हैं, तब तक 8-बिट बायस्ट्रेस का उपयोग नहीं करना चाहिए, जो 8-बिट बायस्ट्रेस (जैसे text_factory = str) की व्याख्या कर सकता है। यह अत्यधिक अनुशंसा की जाती है कि आप केवल यूनिकोड स्ट्रिंग्स के लिए अपने आवेदन को स्विच करें।

क्या आप मुझे इस त्रुटि को हल करने encode("utf-8")और unicode()कार्यों के सही उपयोग की व्याख्या करने में मदद कर सकते हैं ? मैं अक्सर इसके साथ लड़ रहा हूं।

संपादित करें:

इस निष्पादन () कथन में त्रुटि आई:

cur.execute("update docs set path = :fullFilePath where path = :path", locals())

मैं FullFilePath चर के एन्कोडिंग को बदलना भूल गया, जो एक ही समस्या से ग्रस्त है, लेकिन अब मैं काफी उलझन में हूं। क्या मुझे केवल यूनिकोड () या एनकोड ("utf-8") या दोनों का उपयोग करना चाहिए ?

मैं उपयोग नहीं कर सकता

fullFilePath = unicode(fullFilePath.encode("utf-8"))

क्योंकि यह इस त्रुटि को उठाता है:

यूनिकोडडॉफॉर्सेट: 'एससीआई' कोडक 0x5 को स्थिति 32 में बाइट डिकोड नहीं कर सकता है: क्रमिक सीमा में नहीं (128)

पायथन संस्करण 2.7.2 है


वह कोड कहां है जो त्रुटि उठाता है?
न्यूटवर

2
आपके सटीक प्रश्न का उत्तर पहले ही दिया जा चुका है: [ stackoverflow.com/questions/2392732/… [1]: stackoverflow.com/questions/2392732/…
garnertb

@newtover मैंने प्रश्न संपादित किया।
xralf

क्या आपने उपयोग किए गए दोनों चर को रूपांतरित किया है unicode?
न्यूटवर

2
यह सीखते हुए कि पायथन 3 टेक्स्ट और डेटा को कैसे संभालता है, इससे मुझे सब कुछ समझने में मदद मिली। फिर पायथन 2 में ज्ञान को लागू करना आसान है।
ओलेह प्रिनपिन

जवाबों:


87

आप उपयोग कर रहे हैं encode("utf-8") गलत । पायथन बाइट स्ट्रिंग्स ( strप्रकार) में एक एन्कोडिंग है, यूनिकोड नहीं है। आप यूनिकोड स्ट्रिंग को एक पायथन बाइट स्ट्रिंग में uni.encode(encoding)परिवर्तित कर सकते हैं, और आप एक बाइट स्ट्रिंग को यूनिकोड स्ट्रिंग में s.decode(encoding)(या समकक्ष unicode(s, encoding)) का उपयोग करके परिवर्तित कर सकते हैं ।

अगर fullFilePathऔरpath वर्तमान में एक strप्रकार है, तो आपको यह पता लगाना चाहिए कि वे कैसे एन्कोडेड हैं। उदाहरण के लिए, यदि वर्तमान एन्कोडिंग utf-8 है, तो आप उपयोग करेंगे:

path = path.decode('utf-8')
fullFilePath = fullFilePath.decode('utf-8')

यदि यह इसे ठीक नहीं करता है, तो वास्तविक मुद्दा यह हो सकता है कि आप अपने execute()कॉल में यूनिकोड स्ट्रिंग का उपयोग नहीं कर रहे हैं , इसे निम्न में बदलने का प्रयास करें:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())

यह कथन fullFilePath = fullFilePath.decode("utf-8")अभी भी त्रुटि उठाता है UnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: ordinal not in range(128)। fullFilePath db टेबल के टेक्स्ट कॉलम से लिया गया प्रकार str और string का एक संयोजन है जिसे utf-8 एन्कोडिंग होना चाहिए।
xralf

के अनुसार इस लेकिन यह UTF-8, UTF-16BE या UTF-16LE हो सकता है। क्या मैं किसी तरह इसका पता लगा सकता हूं?
xralf

@xralf, यदि आप विभिन्न strवस्तुओं को मिला रहे हैं तो आप एन्कोडिंग को मिला सकते हैं। क्या आप इसका परिणाम दिखा सकते हैं print repr(fullFilePath)?
एंड्रयू क्लार्क

मैं इसे केवल डीकोड () के कॉल से पहले दिखा सकता हूं । समस्याग्रस्त वर्ण \ u0161 और \ u0165 हैं।
xralf

@xralf - तो यह पहले से ही यूनिकोड है? यूनिकोड में निष्पादित कॉल को बदलने का प्रयास करें:cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())
एंड्रयू क्लार्क

121

str बाइट्स में पाठ प्रतिनिधित्व है, unicode में पाठ प्रतिनिधित्व है, वर्णों में पाठ प्रतिनिधित्व है।

आप पाठ को बाइट्स से यूनिकोड तक डिकोड करते हैं और कुछ एन्कोडिंग के साथ एक यूनिकोड को बाइट्स में एनकोड करते हैं।

अर्थात्:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc' 

1
बहुत अच्छा जवाब, सीधे मुद्दे पर। मैं जोड़ूंगा कि unicodeअक्षरों या प्रतीकों के बारे में बोलता हूं , या अधिक उदारता से: दौड़ता है जबकि strएक निश्चित एन्कोडिंग में बाइट्स स्ट्रिंग का प्रतिनिधित्व करता है, जिसे आपको decodeविशिष्ट
रनर

1

सुनिश्चित करें कि आपने शेल से स्क्रिप्ट को चलाने से ठीक पहले अपनी लोकेल सेटिंग सेट की है, जैसे

$ locale -a | grep "^en_.\+UTF-8"
en_GB.UTF-8
en_US.UTF-8
$ export LC_ALL=en_GB.UTF-8
$ export LANG=en_GB.UTF-8

डॉक्स: man locale, man setlocale

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