2015-01-29 11 views
69

के साथ एक अजगर 2 ऑब्जेक्ट को अनपिकलिंग करना मुझे आश्चर्य है कि पाइथन 3.4 के साथ पाइथन 2.4 में उठाए गए ऑब्जेक्ट को लोड करने का कोई तरीका है या नहीं।पायथन 3

मैं इसे अद्यतित करने के लिए बड़ी संख्या में कंपनी विरासत कोड पर 2to3 चला रहा हूं।

यह किया है, जब फ़ाइल मैं निम्नलिखित त्रुटि मिलती चल:

File "H:\fixers - 3.4\addressfixer - 3.4\trunk\lib\address\address_generic.py" 
, line 382, in read_ref_files 
    d = pickle.load(open(mshelffile, 'rb')) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1: ordinal 
not in range(128) 

विवाद में मसालेदार वस्तु को देख, यह एक dict में एक dict है, कुंजी और प्रकार str के मूल्यों से युक्त।

तो मेरा सवाल यह है कि: क्या ऑब्जेक्ट लोड करने का कोई तरीका है, मूल रूप से पायथन 3.4 में पाइथन 3.4 में उठाया गया है?

+0

करता अजगर 2.4 'json' मॉड्यूल है देखते हैं? शायद आप एक 2.4 स्क्रिप्ट लिख सकते हैं जो ऑब्जेक्ट को अनपिक करता है और इसे जेसन ऑब्जेक्ट के रूप में सहेजता है, और फिर एक 3.4 स्क्रिप्ट लिखता है जो जेसन ऑब्जेक्ट को पढ़ता है और इसे 3.4-संगत अचार ऑब्जेक्ट के रूप में सहेजता है। यह एक बार का ऑपरेशन होगा जो आप अपनी सभी अचार फ़ाइलों पर चलते हैं। – Kevin

+0

मैं इसी तरह के लाइनों के साथ सोच रहा था, क्योंकि ये मानते हैं कि मैं सिर्फ एक फाइल में sys.stdout बदल सकता हूं और उन्हें प्रिंट कर सकता हूं, लेकिन मैं देखना चाहता हूं कि मैं उन्हें पहले लोड कर सकता हूं या नहीं – Scironic

उत्तर

110

आपको pickle.load() को पाइथन बायटेस्ट्रिंग डेटा को पायथन 3 स्ट्रिंग में कनवर्ट करना होगा, या आप pickle को बाइट्स के रूप में छोड़ने के लिए बता सकते हैं।

डिफ़ॉल्ट रूप से सभी स्ट्रिंग डेटा को ASCII के रूप में चलाने और डीकोड करना है, और यह डिकोडिंग विफल हो जाती है। pickle.load() documentation देखें:

Optional keyword arguments are fix_imports, encoding and errors, which are used to control compatibility support for pickle stream generated by Python 2. If fix_imports is true, pickle will try to map the old Python 2 names to the new names used in Python 3. The encoding and errors tell pickle how to decode 8-bit string instances pickled by Python 2; these default to ‘ASCII’ and ‘strict’, respectively. The encoding can be ‘bytes’ to read these 8-bit string instances as bytes objects.

latin1 लिए एन्कोडिंग सेट करने से आपको सीधे डेटा आयात करने के लिए अनुमति देता है:

with open(mshelffile, 'rb') as f: 
    d = pickle.load(f, encoding='latin1') 

लेकिन आप अपने तार कि कोई भी गलत कोडेक का उपयोग डीकोड कर रहे हैं सत्यापित करना होगा; लैटिन -1 किसी भी इनपुट के लिए काम करता है क्योंकि यह बाइट मान 0-255 को पहले 256 यूनिकोड कोडपॉइंट्स पर सीधे मैप करता है।

विकल्प encoding='bytes' के साथ डेटा लोड करना होगा, और बाद में bytes कुंजी और मानों को डीकोड करना होगा।

+1

इसे पिछड़ा संगत कैसे बनाया जा सकता है पायथन 2? जाहिर है, पाइथन 2 के लिए एन्कोडिंग तर्क मौजूद नहीं है। – EpicAdv

+1

@EpicAdv: आपको यह कोड पायथन 2 के साथ संगत बनाने की आवश्यकता नहीं है; यह सवाल पाइथन 3 में पाइथन 2 अचार को लोड करने के बारे में है। पायथन 2 के लिए 'एन्कोडिंग' कीवर्ड को पूरी तरह से ड्रॉप करें। –

+6

@EpicAdv: आप एक pickle_options शब्दकोश बना सकते हैं जो या तो अजगर 2 के लिए खाली है या 'एन्कोडिंग' है: ' लैटिन 1 'और अचार के लिए \ * \ * pickle_options भेजें। इस तरह यह दोनों संस्करणों में चलना चाहिए। – pipefish

0

एन्कोडिंग = 'latin1' का उपयोग करने से कुछ समस्याएं होती हैं जब आपके ऑब्जेक्ट में इसमें numpy arrays होते हैं।

एन्कोडिंग = बाइट्स का उपयोग करना बेहतर होगा।

कृपया इस answer