Python 3.7 - pickle

अचार - पायथन वस्तु क्रमांकन




python

अचार - पायथन वस्तु क्रमांकन

स्रोत कोड: Lib/pickle.py

pickle मॉड्यूल एक पायथन ऑब्जेक्ट संरचना को क्रमबद्ध और डी-सीरियल करने के लिए द्विआधारी प्रोटोकॉल को लागू करता है। "पिकलिंग" वह प्रक्रिया है जिसके द्वारा एक पायथन ऑब्जेक्ट पदानुक्रम को बाइट स्ट्रीम में परिवर्तित किया जाता है, और "अनप्लिकिंग" उलटा ऑपरेशन होता है, जिससे एक बाइट स्ट्रीम (एक बाइनरी फ़ाइल या बाइट्स जैसी ऑब्जेक्ट से ) एक ऑब्जेक्ट पदानुक्रम में परिवर्तित हो जाती है। अचार (और unpickling) को वैकल्पिक रूप से "क्रमांकन", "मार्शलिंग," [1] या "चपटा" के रूप में जाना जाता है; हालांकि, भ्रम की स्थिति से बचने के लिए, यहां उपयोग किए जाने वाले शब्द "अचार" और "अप्रभावी" हैं।

चेतावनी

अशुद्ध या गलत तरीके से बनाए गए डेटा के खिलाफ pickle मॉड्यूल सुरक्षित नहीं है। एक अविश्वसनीय या बिना स्रोत के प्राप्त डेटा को कभी भी अनपिक नहीं करें।

अन्य पायथन मॉड्यूल से संबंध

marshal तुलना

पायथन में marshal नाम से एक अधिक आदिम क्रमबद्ध मॉड्यूल है, लेकिन सामान्य pickle हमेशा पायथन वस्तुओं को क्रमबद्ध करने का पसंदीदा तरीका होना चाहिए। marshal मुख्य रूप से पायथन की .pyc फ़ाइलों का समर्थन करने के लिए मौजूद है।

pickle मॉड्यूल कई महत्वपूर्ण तरीकों से marshal से भिन्न होता है:

  • pickle मॉड्यूल उन वस्तुओं का ट्रैक रखता है जो पहले से ही क्रमबद्ध हैं, ताकि बाद में उसी वस्तु के संदर्भों को फिर से क्रमबद्ध नहीं किया जाएगा। marshal ऐसा नहीं करता है।

    यह पुनरावर्ती वस्तुओं और वस्तु साझाकरण दोनों के लिए निहितार्थ है। पुनरावर्ती वस्तुएँ वे वस्तुएँ होती हैं जिनमें स्वयं के संदर्भ होते हैं। ये मार्शल द्वारा नियंत्रित नहीं किए जाते हैं, और वास्तव में, मार्शल की पुनरावर्ती वस्तुओं का प्रयास आपके पायथन दुभाषिया को दुर्घटनाग्रस्त कर देगा। ऑब्जेक्ट शेयरिंग तब होती है जब ऑब्जेक्ट पदानुक्रम में विभिन्न स्थानों में एक ही ऑब्जेक्ट के कई संदर्भों को क्रमबद्ध किया जा रहा है। pickle केवल एक बार ऐसी वस्तुओं को संग्रहीत करता है, और यह सुनिश्चित करता है कि अन्य सभी संदर्भ मास्टर कॉपी को इंगित करते हैं। साझा किए गए ऑब्जेक्ट साझा किए जाते हैं, जो कि परिवर्तनशील वस्तुओं के लिए बहुत महत्वपूर्ण हो सकते हैं।

  • marshal को उपयोगकर्ता-परिभाषित वर्गों और उनके उदाहरणों को क्रमबद्ध करने के लिए उपयोग नहीं किया जा सकता है। pickle पारदर्शी रूप से कक्षा के उदाहरणों को बचा सकता है और पुनर्स्थापित कर सकता है, हालांकि कक्षा की परिभाषा आयात करने योग्य होनी चाहिए और उसी मॉड्यूल में रहना चाहिए जब ऑब्जेक्ट संग्रहीत किया गया था।
  • marshal संस्करणों में marshal क्रमांकन प्रारूप पोर्टेबल होने की गारंटी नहीं है। क्योंकि जीवन में इसका प्राथमिक काम .pyc फ़ाइलों का समर्थन .pyc है, पायथन कार्यान्वयनकर्ताओं को गैर-पिछड़े संगत तरीकों में क्रमांकन प्रारूप को बदलने का अधिकार सुरक्षित रखना चाहिए। pickle क्रमबद्धता प्रारूप को पायथन रिलीज के दौरान पीछे की ओर संगत होने की गारंटी है।

जोंस से तुलना

अचार प्रोटोकॉल और JSON (जावास्क्रिप्ट ऑब्जेक्ट संकेतन) के बीच बुनियादी अंतर हैं:

  • JSON एक टेक्स्ट सीरियलाइज़ेशन प्रारूप है (यह यूनिकोड टेक्स्ट को आउटपुट करता है, हालांकि अधिकांश समय इसे तब utf-8 एन्कोड किया जाता है), जबकि अचार एक द्विआधारी सीरियलाइज़ेशन प्रारूप है;
  • JSON मानव-पठनीय है, जबकि अचार नहीं है;
  • JSON अजगर के पारिस्थितिकी तंत्र के बाहर अंतर और व्यापक रूप से उपयोग किया जाता है, जबकि अचार पायथन-विशिष्ट है;
  • JSON, डिफ़ॉल्ट रूप से, केवल पायथन के एक उप-प्रकार का प्रतिनिधित्व कर सकता है, और कोई कस्टम वर्ग नहीं; अचार एक बहुत बड़ी संख्या में पायथन प्रकारों का प्रतिनिधित्व कर सकता है (उनमें से कई स्वचालित रूप से, पायथन के आत्मनिरीक्षण सुविधाओं के चतुर उपयोग से; विशिष्ट वस्तु एपीआई को लागू करके जटिल मामलों से निपटा जा सकता है)।

यह भी देखें

json मॉड्यूल: JSON सीरियलाइज़ेशन और डीरिएरलाइज़ेशन की अनुमति देने वाला एक मानक लाइब्रेरी मॉड्यूल।

डेटा स्ट्रीम प्रारूप

pickle द्वारा उपयोग किया जाने वाला डेटा प्रारूप पायथन-विशिष्ट है। इसका यह फायदा है कि JSON या XDR (जो पॉइंटर शेयरिंग का प्रतिनिधित्व नहीं कर सकते) जैसे बाहरी मानकों द्वारा लगाए गए प्रतिबंध नहीं हैं; हालांकि इसका मतलब यह है कि गैर-पायथन कार्यक्रम, अछूते हुए पायथन ऑब्जेक्ट्स को फिर से बनाने में सक्षम नहीं हो सकते हैं।

डिफ़ॉल्ट रूप से, pickle डेटा प्रारूप अपेक्षाकृत कॉम्पैक्ट बाइनरी प्रतिनिधित्व का उपयोग करता है। यदि आपको इष्टतम आकार विशेषताओं की आवश्यकता है, तो आप कुशलता से अचार वाले डेटा को compress कर सकते हैं।

मॉड्यूल pickle द्वारा उत्पन्न डेटा धाराओं का विश्लेषण करने के लिए उपकरण होते हैं। अचार प्रोटोकॉल द्वारा उपयोग किए जाने वाले pickletools बारे में pickletools सोर्स कोड में व्यापक टिप्पणियां हैं।

वर्तमान में 5 अलग-अलग प्रोटोकॉल हैं जिनका उपयोग अचार बनाने के लिए किया जा सकता है। उच्च प्रोटोकॉल का इस्तेमाल किया, हाल ही में पायथन के संस्करण को उत्पादित अचार को पढ़ने के लिए आवश्यक है।

  • प्रोटोकॉल संस्करण 0 मूल "मानव-पठनीय" प्रोटोकॉल है और पायथन के पुराने संस्करणों के साथ पीछे की ओर संगत है।
  • प्रोटोकॉल संस्करण 1 एक पुराना द्विआधारी प्रारूप है जो पायथन के पुराने संस्करणों के साथ भी संगत है।
  • प्रोटोकॉल संस्करण 2 को पायथन 2.3 में पेश किया गया था। यह नई शैली के वर्ग के बहुत अधिक कुशल अचार प्रदान करता है। प्रोटोकॉल 2 द्वारा लाए गए सुधारों की जानकारी के लिए पीईपी 307 देखें।
  • प्रोटोकॉल संस्करण 3 पायथन 3.0 में जोड़ा गया था। इसमें bytes ऑब्जेक्ट्स के लिए स्पष्ट समर्थन है और अजगर 2.x द्वारा अप्रकाशित नहीं किया जा सकता है। यह डिफ़ॉल्ट प्रोटोकॉल है, और अनुशंसित प्रोटोकॉल जब अन्य पायथन 3 संस्करणों के साथ संगतता आवश्यक है।
  • प्रोटोकॉल संस्करण 4 पायथन 3.4 में जोड़ा गया था। यह बहुत बड़ी वस्तुओं के लिए समर्थन जोड़ता है, वस्तुओं के अधिक प्रकार और कुछ डेटा प्रारूप अनुकूलन का चयन करता है। प्रोटोकॉल 4 द्वारा लाए गए सुधारों की जानकारी के लिए पीईपी 3154 का संदर्भ लें।

ध्यान दें

हठ की तुलना में सीरियलाइज़ेशन एक अधिक आदिम धारणा है; हालांकि pickle फ़ाइल ऑब्जेक्ट्स को पढ़ता है और लिखता है, यह लगातार वस्तुओं के नामकरण के मुद्दे को संभालता नहीं है, और न ही (और भी जटिल) लगातार वस्तुओं के समवर्ती उपयोग के मुद्दे को। pickle मॉड्यूल एक जटिल वस्तु को बाइट स्ट्रीम में बदल सकता है और यह बाइट स्ट्रीम को उसी आंतरिक संरचना के साथ ऑब्जेक्ट में बदल सकता है। शायद इन बाइट धाराओं के साथ करने के लिए सबसे स्पष्ट बात यह है कि उन्हें एक फ़ाइल पर लिखना है, लेकिन उन्हें एक नेटवर्क पर भेजने या डेटाबेस में संग्रहीत करने के लिए भी यह कल्पनीय है। शेल्व मॉड्यूल, डीबीएम-शैली डेटाबेस फ़ाइलों पर अचार और अनपिकल वस्तुओं के लिए एक सरल इंटरफ़ेस प्रदान करता है।

मॉड्यूल इंटरफ़ेस

किसी वस्तु पदानुक्रम को अनुक्रमित करने के लिए, आप बस dumps() फ़ंक्शन को कॉल करते हैं। इसी तरह, डेटा स्ट्रीम को डी-सीरियल करने के लिए, आप loads() फ़ंक्शन को कॉल करते हैं। हालाँकि, यदि आप क्रमांकन और डी-क्रमांकन पर अधिक नियंत्रण चाहते हैं, तो आप क्रमशः एक Unpickler या Unpickler ऑब्जेक्ट बना सकते हैं।

pickle मॉड्यूल निम्नलिखित स्थिरांक प्रदान करता है:

pickle.HIGHEST_PROTOCOL

एक पूर्णांक, उच्चतम प्रोटोकॉल संस्करण उपलब्ध है। यह मान dump() और dump() और साथ ही Pickler कंस्ट्रक्टर के लिए एक प्रोटोकॉल मान के रूप में पारित किया जा सकता है।

pickle.DEFAULT_PROTOCOL

एक पूर्णांक, डिफ़ॉल्ट प्रोटोकॉल संस्करण जिसे अचार बनाने के लिए उपयोग किया जाता है। HIGHEST_PROTOCOL से कम हो सकता है। वर्तमान में डिफ़ॉल्ट प्रोटोकॉल 3 है, पायथन 3 के लिए डिज़ाइन किया गया एक नया प्रोटोकॉल।

pickle प्रक्रिया को अधिक सुविधाजनक बनाने के लिए pickle मॉड्यूल निम्नलिखित कार्य प्रदान करता है:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)

खुली फ़ाइल ऑब्जेक्ट फ़ाइल के लिए obj का एक मसालेदार प्रतिनिधित्व लिखें। यह Pickler(file, protocol).dump(obj) बराबर है।

वैकल्पिक प्रोटोकॉल तर्क, एक पूर्णांक, पिकर को दिए गए प्रोटोकॉल का उपयोग करने के लिए कहता है; समर्थित प्रोटोकॉल 0 से HIGHEST_PROTOCOL । यदि निर्दिष्ट नहीं है, तो डिफ़ॉल्ट DEFAULT_PROTOCOL । यदि कोई ऋणात्मक संख्या निर्दिष्ट है, तो HIGHEST_PROTOCOL चयनित है।

फ़ाइल तर्क में एक लिखना होगा () विधि जो एकल बाइट्स तर्क को स्वीकार करती है। यह इस प्रकार द्विआधारी लेखन, एक io.BytesIO उदाहरण, या किसी अन्य कस्टम ऑब्जेक्ट के लिए खोली गई ऑन-डिस्क फ़ाइल हो सकती है जो इस इंटरफ़ेस से मिलती है।

यदि fix_imports सच है और प्रोटोकॉल 3 से कम है, तो अचार नए पायथन 3 नामों को पायथन 2 में उपयोग किए गए पुराने मॉड्यूल नामों को मैप करने की कोशिश करेगा, ताकि पायल 2 के साथ अचार डेटा स्ट्रीम पठनीय हो।

pickle.dumps(obj, protocol=None, *, fix_imports=True)

किसी bytes ऑब्जेक्ट के रूप में ऑब्जेक्ट के अचारयुक्त प्रतिनिधित्व को एक फाइल में लिखने के बजाय वापस करें।

तर्क प्रोटोकॉल और Fix_imports का dump() के समान अर्थ है।

pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict")

खुली हुई फ़ाइल ऑब्जेक्ट फ़ाइल से एक मसालेदार ऑब्जेक्ट प्रतिनिधित्व पढ़ें और उसमें निर्दिष्ट पुनर्गठित ऑब्जेक्ट पदानुक्रम वापस करें। यह Unpickler(file).load() बराबर है।

अचार के प्रोटोकॉल संस्करण का स्वचालित रूप से पता लगाया जाता है, इसलिए किसी प्रोटोकॉल तर्क की आवश्यकता नहीं है। बाइट्स में पिछले ऑब्जेक्ट के प्रतिनिधित्व को नजरअंदाज कर दिया जाता है।

तर्क फ़ाइल में दो विधियाँ होनी चाहिए, एक रीड () विधि जो पूर्णांक तर्क लेती है, और एक रीडलाइन () विधि जिसमें कोई तर्क की आवश्यकता होती है। दोनों तरीकों को बाइट्स लौटना चाहिए। इस प्रकार फ़ाइल बाइनरी रीडिंग, io.BytesIO ऑब्जेक्ट या किसी अन्य कस्टम ऑब्जेक्ट के लिए खोली गई ऑन-डिस्क फ़ाइल हो सकती है जो इस इंटरफ़ेस से मिलती है।

वैकल्पिक कीवर्ड तर्क fix_imports , एन्कोडिंग और त्रुटियाँ हैं , जिनका उपयोग Python 2 द्वारा उत्पन्न अचार स्ट्रीम के लिए संगतता समर्थन को नियंत्रित करने के लिए किया जाता है। यदि Fix_imports सत्य है, तो Python 3 में उपयोग किए गए नए नाम के लिए अचार पुराने Python 2 नामों को मैप करने का प्रयास करेगा। एन्कोडिंग और त्रुटियां अचार को बताती हैं कि पायथन 2 द्वारा उठाए गए 8-बिट स्ट्रिंग इंस्टेंस को कैसे डीकोड किया जाए; क्रमशः 'ASCII' और 'सख्त' के लिए ये डिफ़ॉल्ट हैं। इन 8-बिट स्ट्रिंग इंस्टेंस को बाइट ऑब्जेक्ट के रूप में पढ़ने के लिए एन्कोडिंग 'बाइट्स' हो सकता है।

pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")

एक bytes ऑब्जेक्ट से एक मसालेदार वस्तु पदानुक्रम पढ़ें और उसमें निर्दिष्ट पुनर्गठित वस्तु पदानुक्रम वापस करें।

अचार के प्रोटोकॉल संस्करण का स्वचालित रूप से पता लगाया जाता है, इसलिए किसी प्रोटोकॉल तर्क की आवश्यकता नहीं है। बाइट्स में पिछले ऑब्जेक्ट के प्रतिनिधित्व को नजरअंदाज कर दिया जाता है।

वैकल्पिक कीवर्ड तर्क fix_imports , एन्कोडिंग और त्रुटियाँ हैं , जिनका उपयोग Python 2 द्वारा उत्पन्न अचार स्ट्रीम के लिए संगतता समर्थन को नियंत्रित करने के लिए किया जाता है। यदि Fix_imports सत्य है, तो Python 3 में उपयोग किए गए नए नाम के लिए अचार पुराने Python 2 नामों को मैप करने का प्रयास करेगा। एन्कोडिंग और त्रुटियां अचार को बताती हैं कि पायथन 2 द्वारा उठाए गए 8-बिट स्ट्रिंग इंस्टेंस को कैसे डीकोड किया जाए; क्रमशः 'ASCII' और 'सख्त' के लिए ये डिफ़ॉल्ट हैं। इन 8-बिट स्ट्रिंग इंस्टेंस को बाइट ऑब्जेक्ट के रूप में पढ़ने के लिए एन्कोडिंग 'बाइट्स' हो सकता है।

pickle मॉड्यूल तीन अपवादों को परिभाषित करता है:

exception pickle.PickleError

अन्य अचार अपवादों के लिए सामान्य आधार वर्ग। यह Exception

exception pickle.PicklingError

पिकलर द्वारा किसी अयोग्य वस्तु का सामना करने पर त्रुटि उत्पन्न हुई। यह PickleError विरासत में मिली है।

संदर्भ लें कि क्या अचार और अनपैक किया जा सकता है? यह जानने के लिए कि किस प्रकार की वस्तुओं को चुना जा सकता है।

exception pickle.UnpicklingError

डेटा ऑब्जेक्ट या सुरक्षा उल्लंघन जैसे किसी ऑब्जेक्ट को अनप्लिक करने में कोई समस्या होने पर त्रुटि हुई। यह PickleError विरासत में मिली है।

ध्यान दें कि अन्य अपवाद भी unpickling के दौरान उठाए जा सकते हैं, जिसमें (लेकिन जरूरी नहीं कि यह तक सीमित हो) विशेषता, EOFError, ImportError, और IndexError शामिल हैं।

pickle मॉड्यूल दो वर्गों, Pickler और Unpickler निर्यात करता है:

class pickle.Pickler(file, protocol=None, *, fix_imports=True)

यह अचार डेटा स्ट्रीम लिखने के लिए एक बाइनरी फ़ाइल लेता है।

वैकल्पिक प्रोटोकॉल तर्क, एक पूर्णांक, पिकर को दिए गए प्रोटोकॉल का उपयोग करने के लिए कहता है; समर्थित प्रोटोकॉल 0 से HIGHEST_PROTOCOL । यदि निर्दिष्ट नहीं है, तो डिफ़ॉल्ट DEFAULT_PROTOCOL । यदि कोई ऋणात्मक संख्या निर्दिष्ट है, तो HIGHEST_PROTOCOL चयनित है।

फ़ाइल तर्क में एक लिखना होगा () विधि जो एकल बाइट्स तर्क को स्वीकार करती है। यह इस प्रकार द्विआधारी लेखन, एक io.BytesIO उदाहरण, या किसी अन्य कस्टम ऑब्जेक्ट के लिए खोली गई ऑन-डिस्क फ़ाइल हो सकती है जो इस इंटरफ़ेस से मिलती है।

यदि fix_imports सच है और प्रोटोकॉल 3 से कम है, तो अचार नए पायथन 3 नामों को पायथन 2 में उपयोग किए गए पुराने मॉड्यूल नामों को मैप करने की कोशिश करेगा, ताकि पायल 2 के साथ अचार डेटा स्ट्रीम पठनीय हो।

dump(obj)

कंस्ट्रक्टर में दिए गए ओपन फाइल ऑब्जेक्ट के लिए ओब्जेक्ट का एक अटेन्डेड प्रतिनिधित्व लिखें।

persistent_id(obj)

कुछ भी डिफ़ॉल्ट रूप से मत करो। यह मौजूद है इसलिए एक उपवर्ग इसे ओवरराइड कर सकता है।

यदि persistent_id() None लौटाता है, तो obj को सामान्य रूप से चुना जाता है। कोई भी अन्य मूल्य Pickler को Pickler लिए एक स्थिर आईडी के रूप में लौटाए गए मूल्य का उत्सर्जन करने का कारण बनता है। इस निरंतर आईडी का अर्थ Unpickler.persistent_load() द्वारा परिभाषित किया जाना चाहिए। ध्यान दें कि persistent_id() द्वारा लौटाया गया मान स्वयं एक स्थायी ID नहीं हो सकता है।

विवरणों और उपयोगों के उदाहरणों के लिए बाहरी वस्तुओं की दृढ़ता देखें।

dispatch_table

पिकर ऑब्जेक्ट की प्रेषण तालिका उस प्रकार के कटौती कार्यों की एक रजिस्ट्री है, जिसे copyreg.pickle() का उपयोग करके घोषित किया जा सकता है। यह एक मानचित्रण है जिसकी कुंजी वर्ग हैं और जिनके मानों में कटौती कार्य हैं। एक कमी फ़ंक्शन संबद्ध वर्ग का एकल तर्क लेता है और इसे __reduce__() विधि के समान इंटरफ़ेस के अनुरूप होना चाहिए।

डिफ़ॉल्ट रूप से, एक पिकलर ऑब्जेक्ट में एक डिस्पैच_टेबल विशेषता नहीं होगी, और यह इसके बजाय copyreg मॉड्यूल द्वारा प्रबंधित वैश्विक प्रेषण तालिका का उपयोग करेगा। हालाँकि, किसी विशिष्ट पिकर ऑब्जेक्ट के लिए अचार को अनुकूलित करने के लिए डिस्पैच_टेबल विशेषता को एक तानाशाह जैसी वस्तु पर सेट कर सकते हैं। वैकल्पिक रूप से, यदि Pickler उपवर्ग में एक dispatch_table विशेषता है, तो इसका उपयोग उस वर्ग के उदाहरणों के लिए डिफ़ॉल्ट प्रेषण तालिका के रूप में किया जाएगा।

उपयोग उदाहरणों के लिए डिस्पैच टेबल देखें।

संस्करण 3.3 में नया।

fast

पदावनत। सही मान पर सेट होने पर तेज़ मोड सक्षम करें। फास्ट मोड मेमो के उपयोग को अक्षम करता है, इसलिए शानदार पीयूटी ओपकोड उत्पन्न करके अचार की प्रक्रिया को तेज करता है। इसका उपयोग स्वयं-संदर्भित वस्तुओं के साथ नहीं किया जाना चाहिए, अन्यथा Pickler को असीम रूप से पुनर्जीवित करने का कारण होगा।

यदि आपको अधिक कॉम्पैक्ट अचार की आवश्यकता है, तो pickletools.optimize() उपयोग करें।

class pickle.Unpickler(file, *, fix_imports=True, encoding="ASCII", errors="strict")

यह अचार डेटा स्ट्रीम पढ़ने के लिए एक बाइनरी फ़ाइल लेता है।

अचार के प्रोटोकॉल संस्करण का स्वचालित रूप से पता लगाया जाता है, इसलिए किसी प्रोटोकॉल तर्क की आवश्यकता नहीं है।

तर्क फ़ाइल में दो विधियाँ होनी चाहिए, एक रीड () विधि जो पूर्णांक तर्क लेती है, और एक रीडलाइन () विधि जिसमें कोई तर्क की आवश्यकता होती है। दोनों तरीकों को बाइट्स लौटना चाहिए। इस प्रकार फ़ाइल बाइनरी रीडिंग के लिए खोली गई ऑन-डिस्क फ़ाइल ऑब्जेक्ट हो सकती है, एक io.BytesIO ऑब्जेक्ट, या कोई अन्य कस्टम ऑब्जेक्ट जो इस इंटरफ़ेस से मिलता है।

वैकल्पिक कीवर्ड तर्क fix_imports , एन्कोडिंग और त्रुटियाँ हैं , जिनका उपयोग Python 2 द्वारा उत्पन्न अचार स्ट्रीम के लिए संगतता समर्थन को नियंत्रित करने के लिए किया जाता है। यदि Fix_imports सत्य है, तो Python 3 में उपयोग किए गए नए नाम के लिए अचार पुराने Python 2 नामों को मैप करने का प्रयास करेगा। एन्कोडिंग और त्रुटियां अचार को बताती हैं कि पायथन 2 द्वारा उठाए गए 8-बिट स्ट्रिंग इंस्टेंस को कैसे डीकोड किया जाए; क्रमशः 'ASCII' और 'सख्त' के लिए ये डिफ़ॉल्ट हैं। इन 8-बिट स्ट्रिंग इंस्टेंस को बाइट ऑब्जेक्ट के रूप में पढ़ने के लिए एन्कोडिंग 'बाइट्स' हो सकता है।

load()

कंस्ट्रक्टर में दी गई खुली फ़ाइल ऑब्जेक्ट से एक मसालेदार ऑब्जेक्ट प्रतिनिधित्व पढ़ें, और उसमें निर्दिष्ट पुनर्गठित ऑब्जेक्ट पदानुक्रम लौटाएं। बाइट्स में पिछले ऑब्जेक्ट के प्रतिनिधित्व को नजरअंदाज कर दिया जाता है।

persistent_load(pid)

डिफ़ॉल्ट रूप से एक UnpicklingError उठाएँ।

यदि परिभाषित किया गया है, तो Unpickler.persistent_load() लगातार ID pid द्वारा निर्दिष्ट ऑब्जेक्ट को वापस करना चाहिए। यदि एक अवैध लगातार आईडी का सामना करना पड़ा है, तो एक UnpicklingError को उठाया जाना चाहिए।

विवरणों और उपयोगों के उदाहरणों के लिए बाहरी वस्तुओं की दृढ़ता देखें।

find_class(module, name)

यदि आवश्यक हो तो मॉड्यूल आयात करें और उस ऑब्जेक्ट को नाम से लौटाएं, जहां मॉड्यूल और नाम तर्क str ऑब्जेक्ट हैं। नोट, इसके नाम के विपरीत, find_class() का उपयोग फ़ंक्शन खोजने के लिए भी किया जाता है।

उप-वर्ग इस पर काबू पा सकते हैं कि किस प्रकार की वस्तुओं पर नियंत्रण पाने के लिए और उन्हें कैसे लोड किया जा सकता है, संभवतः सुरक्षा जोखिमों को कम करता है। विवरण के लिए प्रतिबंधित ग्लोबल्स देखें।

क्या उठाया जा सकता है और unpickled?

निम्नलिखित प्रकारों को चुना जा सकता है:

  • None , True और False
  • पूर्णांक, फ्लोटिंग पॉइंट संख्या, जटिल संख्या
  • तार, बाइट्स, बायट्रीज़
  • tuples, सूचियाँ, सेट, और केवल अकल्पनीय वस्तुओं वाले शब्दकोशों
  • मॉड्यूल के शीर्ष स्तर पर परिभाषित कार्य ( def का उपयोग करते हुए, lambda नहीं)
  • एक मॉड्यूल के शीर्ष स्तर पर परिभाषित कार्य
  • एक मॉड्यूल के शीर्ष स्तर पर परिभाषित की जाने वाली कक्षाएं
  • ऐसे वर्गों के उदाहरण जिनकी __dict__ या __getstate__() को कॉल करने का परिणाम है __getstate__() विवरण के लिए अनुभाग पिकिंग क्लास इंस्टेंस देखें)।

अयोग्य वस्तुओं को अचार करने के प्रयास से पिकलिंग एवरर अपवाद उठेगा; जब ऐसा होता है, तो एक अनिर्दिष्ट संख्या बाइट्स पहले से ही अंतर्निहित फ़ाइल को लिखा जा सकता है। एक अत्यधिक पुनरावर्ती डेटा संरचना को अचार करने की कोशिश अधिकतम पुनरावृत्ति की गहराई को पार कर सकती है, इस मामले में एक RecursionError उठाया जाएगा। आप इस सीमा को ध्यान से sys.setrecursionlimit() साथ बढ़ा सकते हैं।

ध्यान दें कि फ़ंक्शंस (बिल्ट-इन और यूज़र-डिफ़ाइंड) को "पूरी तरह से योग्य" नाम संदर्भ द्वारा चुना गया है, न कि मूल्य द्वारा। [2] इसका मतलब है कि केवल फ़ंक्शन नाम को चुना गया है, मॉड्यूल के नाम के साथ फ़ंक्शन को परिभाषित किया गया है। न तो फ़ंक्शन का कोड, और न ही इसके फ़ंक्शन विशेषताओं में से कोई भी पिक किया गया है। इस प्रकार परिभाषित मॉड्यूल unpickling वातावरण में आयात करने योग्य होना चाहिए, और मॉड्यूल में नामित ऑब्जेक्ट होना चाहिए, अन्यथा एक अपवाद उठाया जाएगा। [3]

इसी तरह, कक्षाओं को नामांकित संदर्भ द्वारा चुना जाता है, इसलिए अप्रकाशित वातावरण में समान प्रतिबंध लागू होते हैं। ध्यान दें कि कक्षा का कोई भी कोड या डेटा नहीं लिया गया है, इसलिए निम्न उदाहरण में वर्ग विशेषता attr को unpickling वातावरण में पुनर्स्थापित नहीं किया गया है:

class Foo:
    attr = 'A class attribute'

picklestring = pickle.dumps(Foo)

ये प्रतिबंध इसीलिए हैं कि पिकलेबल फ़ंक्शंस और कक्षाओं को एक मॉड्यूल के शीर्ष स्तर में परिभाषित किया जाना चाहिए।

इसी तरह, जब क्लास इंस्टेंस को पिक किया जाता है, तो उनके क्लास के कोड और डेटा को भी साथ नहीं लिया जाता है। केवल उदाहरण डेटा को चुना जाता है। यह उद्देश्य से किया जाता है, इसलिए आप एक वर्ग में बग्स को ठीक कर सकते हैं या कक्षा में विधियों को जोड़ सकते हैं और अभी भी उन वस्तुओं को लोड कर सकते हैं जो कक्षा के पुराने संस्करण के साथ बनाए गए थे। यदि आपके पास लंबे समय तक रहने वाली वस्तुओं की योजना है जो एक वर्ग के कई संस्करणों को देखेंगे, तो वस्तुओं में एक संस्करण संख्या डालना सार्थक हो सकता है ताकि कक्षा के __setstate__() विधि द्वारा उपयुक्त रूपांतरण किए जा __setstate__()

अचार कक्षा वर्ग

इस खंड में, हम आपके लिए उपलब्ध सामान्य तंत्रों का वर्णन करते हैं, जिन्हें परिभाषित करने, अनुकूलित करने और नियंत्रित करने के लिए कि किस प्रकार वर्ग उदाहरणों को चुना और अप्रकाशित किया जाता है।

ज्यादातर मामलों में, उदाहरणों को अचूक बनाने के लिए किसी अतिरिक्त कोड की आवश्यकता नहीं होती है। डिफ़ॉल्ट रूप से, अचार आत्मनिरीक्षण के माध्यम से वर्ग और एक उदाहरण की विशेषताओं को पुनः प्राप्त करेगा। जब एक वर्ग उदाहरण अप्रकाशित होता है, तो इसका __init__() विधि आमतौर पर लागू नहीं होती है । डिफ़ॉल्ट व्यवहार पहले एक अनइंस्टाल्यूटेड उदाहरण बनाता है और फिर सहेजे गए गुणों को पुनर्स्थापित करता है। निम्नलिखित कोड इस व्यवहार का कार्यान्वयन दिखाता है:

def save(obj):
    return (obj.__class__, obj.__dict__)

def load(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj

कक्षाएं एक या कई विशेष तरीके प्रदान करके डिफ़ॉल्ट व्यवहार को बदल सकती हैं:

object.__getnewargs_ex__()

प्रोटोकॉल 2 और नए में, __getnewargs_ex__() विधि को लागू करने वाली कक्षाएं __getnewargs_ex__() विधि को __new__() करने के लिए पारित मानों को निर्धारित कर सकती हैं। विधि को एक जोड़ी (args, kwargs) को वापस करना चाहिए जहाँ args स्थितीय तर्कों का एक हिस्सा है और kwargs को ऑब्जेक्ट बनाने के लिए नामित तर्कों का एक शब्दकोश है। जिन्हें __new__() विधि के __new__() करने पर पास किया जाएगा।

यदि आपकी कक्षा के __new__() विधि को केवल-कीवर्ड तर्कों की आवश्यकता है, तो आपको इस विधि को लागू करना चाहिए। अन्यथा, यह __getnewargs__() को लागू करने के लिए संगतता के लिए अनुशंसित है।

संस्करण 3.6 में परिवर्तित: __getnewargs_ex__() अब प्रोटोकॉल 2 और 3 में उपयोग किया जाता है।

object.__getnewargs__()

यह विधि __getnewargs_ex__() रूप में एक समान उद्देश्य प्रदान करती है, लेकिन केवल स्थिति संबंधी तर्कों का समर्थन करती है। इसे तर्कों का एक टपल लौटाना चाहिए जो __new__() होने पर __new__() विधि से पारित हो जाएगा।

__getnewargs__() नहीं कहा जाएगा यदि __getnewargs_ex__() परिभाषित है।

संस्करण 3.6 में बदला: पायथन 3.6 से पहले, प्रोटोकॉल 2 और 3 में __getnewargs_ex__() बजाय __getnewargs_ex__() कहा जाता था।

object.__getstate__()

कक्षाएं आगे प्रभावित कर सकती हैं कि उनके उदाहरण कैसे उठाए जाते हैं; यदि वर्ग विधि __getstate__() को परिभाषित करता है, तो इसे कहा जाता है और रिटर्न ऑब्जेक्ट को उदाहरण की सामग्री के बजाय उदाहरण के लिए सामग्री के रूप में चुना जाता है। यदि __getstate__() विधि अनुपस्थित है, तो उदाहरण के __dict__ को हमेशा की तरह चुना जाता है।

object.__setstate__(state)

__setstate__() होने पर, यदि वर्ग __setstate__() को परिभाषित करता है, तो इसे अप्रकाशित स्थिति के साथ कहा जाता है। उस स्थिति में, राज्य ऑब्जेक्ट के लिए एक शब्दकोश होने की कोई आवश्यकता नहीं है। अन्यथा, चुना हुआ राज्य एक शब्दकोश होना चाहिए और इसके आइटम नए उदाहरण के शब्दकोश में दिए गए हैं।

ध्यान दें

यदि __getstate__() एक गलत मान देता है, तो __setstate__() विधि को __setstate__() पर नहीं कहा जाएगा।

तरीकों __getstate__() और __setstate__() का उपयोग करने के तरीके के बारे में अधिक जानकारी के लिए स्टेटफुल ऑब्जेक्ट्स को __getstate__() करने वाले अनुभाग को देखें।

ध्यान दें

__getattr__() समय, कुछ तरीकों जैसे __getattr__() , __getattribute__() , या __setattr__() को मिसाल के तौर पर कहा जा सकता है। यदि वे विधियां कुछ आंतरिक अपरिवर्तनीय के सत्य होने पर निर्भर करती हैं, तो इस तरह के एक __getnewargs_ex__() को स्थापित करने के लिए प्रकार को __getnewargs__() या __getnewargs_ex__() को लागू करना चाहिए; अन्यथा, न तो __new__() और न ही __init__() कहा जाएगा।

जैसा कि हम देखेंगे, अचार सीधे ऊपर वर्णित विधियों का उपयोग नहीं करता है। वास्तव में, ये विधियाँ प्रतिलिपि प्रोटोकॉल का हिस्सा हैं जो __reduce__() विशेष विधि को लागू करती हैं। कॉपी प्रोटोकॉल ऑब्जेक्ट को अचार बनाने और कॉपी करने के लिए आवश्यक डेटा प्राप्त करने के लिए एक एकीकृत इंटरफ़ेस प्रदान करता है। [4]

हालांकि शक्तिशाली, __reduce__() सीधे अपनी कक्षाओं में लागू करना त्रुटि प्रवण है। इस कारण से, जब भी संभव हो, क्लास डिजाइनरों को उच्च-स्तरीय इंटरफ़ेस (यानी, __getnewargs_ex__() , __getstate__() और __setstate__() ) का उपयोग करना चाहिए। हालांकि, हम ऐसे मामलों को दिखाएंगे, जिनमें __reduce__() का उपयोग करना एकमात्र विकल्प है या अधिक कुशल अचार या दोनों की ओर जाता है।

object.__reduce__()

वर्तमान में इंटरफ़ेस निम्नानुसार परिभाषित किया गया है। __reduce__() विधि कोई तर्क नहीं लेती है और या तो एक स्ट्रिंग या अधिमानतः टपल लौटेगी (लौटी हुई वस्तु को अक्सर "कम मूल्य" के रूप में संदर्भित किया जाता है)।

यदि एक स्ट्रिंग लौटा दी जाती है, तो स्ट्रिंग को एक वैश्विक चर के नाम के रूप में व्याख्या की जानी चाहिए। यह अपने मॉड्यूल के सापेक्ष ऑब्जेक्ट का स्थानीय नाम होना चाहिए; अचार मॉड्यूल ऑब्जेक्ट के मॉड्यूल को निर्धारित करने के लिए मॉड्यूल नेमस्पेस खोजता है। यह व्यवहार विशेष रूप से एकल के लिए उपयोगी है।

जब एक टपल लौटाया जाता है, तो यह दो और पाँच वस्तुओं के बीच लंबा होना चाहिए। वैकल्पिक वस्तुओं को या तो छोड़ा जा सकता है, या उनके मूल्य के रूप में None भी प्रदान None जा सकता है। प्रत्येक आइटम के शब्दार्थ क्रम में हैं:

  • एक कॉल करने योग्य ऑब्जेक्ट जिसे ऑब्जेक्ट का प्रारंभिक संस्करण बनाने के लिए कहा जाएगा।
  • कॉल करने योग्य वस्तु के लिए तर्कों का एक समूह। खाली ट्यूपल दिया जाना चाहिए यदि कॉल करने योग्य किसी भी तर्क को स्वीकार नहीं करता है।
  • वैकल्पिक रूप से, ऑब्जेक्ट की स्थिति, जिसे पहले वर्णित के __setstate__() ऑब्जेक्ट की __setstate__() विधि से पास किया जाएगा। यदि ऑब्जेक्ट में ऐसी कोई विधि नहीं है, तो मान एक शब्दकोष होना चाहिए और इसे ऑब्जेक्ट की __dict__ विशेषता में जोड़ा जाएगा।
  • वैकल्पिक रूप से, एक पुनरावृत्ति (और अनुक्रम नहीं) क्रमिक वस्तुओं की उपज। ये आइटम ऑब्जेक्ट में या तो obj.append(item) या बैच में, obj.extend(list_of_items) का उपयोग करके obj.extend(list_of_items) । यह मुख्य रूप से सूची उपवर्गों के लिए उपयोग किया जाता है, लेकिन अन्य वर्गों द्वारा तब तक उपयोग किया जा सकता है जब तक उनके पास उचित हस्ताक्षर के साथ append() और extend() विधियां हैं। (चाहे append() या extend() का उपयोग किया जाता है, इस बात पर निर्भर करता है कि अचार प्रोटोकॉल संस्करण का उपयोग किया जाता है और साथ ही एपेंड करने के लिए कितने आइटम हैं, इसलिए दोनों का समर्थन करना चाहिए।
  • वैकल्पिक रूप से, एक इटरेटर (एक अनुक्रम नहीं) क्रमिक कुंजी-मूल्य जोड़े की उपज। इन वस्तुओं को ऑब्जेक्ट obj[key] = value का उपयोग करके ऑब्जेक्ट में संग्रहीत किया जाएगा। यह मुख्य रूप से शब्दकोश उपवर्गों के लिए उपयोग किया जाता है, लेकिन जब तक वे __setitem__() लागू करते हैं, तब तक अन्य वर्गों द्वारा उपयोग किया जा सकता है।
object.__reduce_ex__(protocol)

वैकल्पिक रूप से, एक __reduce_ex__() विधि को परिभाषित किया जा सकता है। फर्क सिर्फ इतना है कि इस विधि को एक पूर्णांक तर्क, प्रोटोकॉल संस्करण लेना चाहिए। जब परिभाषित किया जाता है, तो अचार इसे __reduce__() विधि पर पसंद करेगा। इसके अलावा, __reduce__() स्वचालित रूप से विस्तारित संस्करण का एक पर्याय बन जाता है। इस पद्धति का मुख्य उपयोग पुराने पाइथन रिलीज के लिए पीछे की ओर संगत कम मूल्यों को प्रदान करना है।

बाहरी वस्तुओं की दृढ़ता

ऑब्जेक्ट हठ के लाभ के लिए, pickle मॉड्यूल पिकड डेटा स्ट्रीम के बाहर किसी ऑब्जेक्ट के संदर्भ की धारणा का समर्थन करता है। ऐसी वस्तुओं को एक निरंतर आईडी द्वारा संदर्भित किया जाता है, जो या तो अल्फ़ान्यूमेरिक वर्ण (प्रोटोकॉल 0 के लिए) [5] या सिर्फ एक मनमाना ऑब्जेक्ट (किसी भी नए प्रोटोकॉल के लिए) का एक स्ट्रिंग होना चाहिए।

इस तरह के लगातार आईडी के संकल्प को pickle मॉड्यूल द्वारा परिभाषित नहीं किया जाता है; यह इस रिज़ॉल्यूशन को उपयोगकर्ता के चुने हुए तरीकों पर क्रमशः पिकलर और अनपिकलर, persistent_id() और Unpickler.persistent_load()

बाहरी स्थिर आईडी वाले ऑब्जेक्ट को चुनने के लिए, पिकलर के पास एक कस्टम persistent_id() विधि होनी चाहिए जो ऑब्जेक्ट को एक तर्क के रूप में लेती है और उस ऑब्जेक्ट के लिए None या लगातार आईडी None देता है। जब None लौटाया जाता है, तो पिकर सामान्य रूप से ऑब्जेक्ट को अचार करता है। जब एक लगातार आईडी स्ट्रिंग वापस आ जाती है, तो पिकलर उस वस्तु को एक मार्कर के साथ अचार करेगा, ताकि unpickler इसे एक स्थायी आईडी के रूप में पहचान ले।

बाहरी ऑब्जेक्ट्स को अनपिक करने के लिए, unpickler के पास एक कस्टम Unpickler.persistent_load() विधि होनी चाहिए जो एक निरंतर ID ऑब्जेक्ट लेता है और संदर्भित ऑब्जेक्ट को वापस करता है।

यहां एक व्यापक उदाहरण प्रस्तुत किया गया है कि संदर्भ द्वारा बाहरी वस्तुओं को अचार बनाने के लिए लगातार आईडी का उपयोग कैसे किया जा सकता है।

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()

टेबल्स डिस्पैच करें

यदि कोई किसी अन्य कोड को परेशान किए बिना कुछ वर्गों के अचार को अनुकूलित करना चाहता है, जो अचार पर निर्भर करता है, तो कोई एक निजी प्रेषण तालिका के साथ एक पिकर बना सकता है।

copyreg मॉड्यूल द्वारा प्रबंधित वैश्विक प्रेषण तालिका copyreg रूप में उपलब्ध है। इसलिए, एक निजी प्रेषण तालिका के रूप में copyreg.dispatch_table की संशोधित प्रतिलिपि का उपयोग करने का चयन कर सकता है।

उदाहरण के लिए

f = io.BytesIO()
p = pickle.Pickler(f)
p.dispatch_table = copyreg.dispatch_table.copy()
p.dispatch_table[SomeClass] = reduce_SomeClass

एक निजी प्रेषण तालिका के साथ Pickler का एक उदाहरण बनाता है। कुछ विशेष वर्ग को संभालता है। वैकल्पिक रूप से, कोड

class MyPickler(pickle.Pickler):
    dispatch_table = copyreg.dispatch_table.copy()
    dispatch_table[SomeClass] = reduce_SomeClass
f = io.BytesIO()
p = MyPickler(f)

वही करता है, लेकिन MyPickler सभी उदाहरण डिफ़ॉल्ट रूप से एक ही प्रेषण तालिका साझा करेंगे। समकक्ष मॉड्यूल का उपयोग करने copyreg समतुल्य कोड है

copyreg.pickle(SomeClass, reduce_SomeClass)
f = io.BytesIO()
p = pickle.Pickler(f)

स्टेटफुल ऑब्जेक्ट्स को हैंडल करना

यहाँ एक उदाहरण है जो दिखाता है कि क्लास के लिए अचार व्यवहार को कैसे संशोधित किया जाए। TextReader वर्ग एक पाठ फ़ाइल खोलता है, और हर बार इसकी readline() पद्धति को लाइन नंबर और लाइन सामग्री देता है। यदि एक TextReader उदाहरण चुना जाता है, तो फ़ाइल ऑब्जेक्ट सदस्य को छोड़कर सभी विशेषताएँ सहेज ली जाती हैं। जब उदाहरण अप्रकाशित होता है, तो फ़ाइल फिर से खोल दी जाती है, और अंतिम स्थान से रिज्यूमे पढ़ना। इस व्यवहार को लागू करने के लिए __setstate__() और __getstate__() विधियों का उपयोग किया जाता है।

class TextReader:
    """Print and number lines in a text file."""

    def __init__(self, filename):
        self.filename = filename
        self.file = open(filename)
        self.lineno = 0

    def readline(self):
        self.lineno += 1
        line = self.file.readline()
        if not line:
            return None
        if line.endswith('\n'):
            line = line[:-1]
        return "%i: %s" % (self.lineno, line)

    def __getstate__(self):
        # Copy the object's state from self.__dict__ which contains
        # all our instance attributes. Always use the dict.copy()
        # method to avoid modifying the original state.
        state = self.__dict__.copy()
        # Remove the unpicklable entries.
        del state['file']
        return state

    def __setstate__(self, state):
        # Restore instance attributes (i.e., filename and lineno).
        self.__dict__.update(state)
        # Restore the previously opened file's state. To do so, we need to
        # reopen it and read from it until the line count is restored.
        file = open(self.filename)
        for _ in range(self.lineno):
            file.readline()
        # Finally, save the file.
        self.file = file

एक नमूना उपयोग कुछ इस तरह हो सकता है:

>>> reader = TextReader("hello.txt")
>>> reader.readline()
'1: Hello world!'
>>> reader.readline()
'2: I am line number two.'
>>> new_reader = pickle.loads(pickle.dumps(reader))
>>> new_reader.readline()
'3: Goodbye!'

ग्लोबल्स को प्रतिबंधित करना

डिफ़ॉल्ट रूप से, unpickling किसी भी वर्ग या फ़ंक्शन को आयात करेगा जो उसे अचार डेटा में पाता है। कई अनुप्रयोगों के लिए, यह व्यवहार अस्वीकार्य है क्योंकि यह unpickler को आयात करने और मनमाने कोड को लागू करने की अनुमति देता है। जब लोड किया जाता है तो केवल इस हाथ से तैयार अचार डेटा स्ट्रीम पर विचार करें:

>>> import pickle
>>> pickle.loads(b"cos\nsystem\n(S'echo hello world'\ntR.")
hello world
0

इस उदाहरण में, unpickler os.system() फ़ंक्शन आयात करता है और फिर स्ट्रिंग तर्क "इको हेल्लो वर्ल्ड" लागू करता है। हालांकि यह उदाहरण अप्रभावी है, लेकिन यह कल्पना करना मुश्किल नहीं है कि आपके सिस्टम को नुकसान हो सकता है।

इस कारण से, आप यह नियंत्रित करना चाह सकते हैं कि अनुकूलित करने से क्या अप्रभावित हो जाता है find_class() । इसके नाम के विपरीत, find_class() जब भी एक वैश्विक (यानी, एक वर्ग या एक समारोह) का अनुरोध किया जाता है। इस प्रकार यह संभव है कि या तो पूरी तरह से ग्लोबल्स को निषिद्ध करें या उन्हें एक सुरक्षित सबसेट तक सीमित करें।

यहाँ एक unpickler का उदाहरण दिया गया है जो builtins मॉड्यूल से केवल कुछ सुरक्षित वर्गों को लोड करने की अनुमति देता है :

import builtins
import io
import pickle

safe_builtins = {
    'range',
    'complex',
    'set',
    'frozenset',
    'slice',
}

class RestrictedUnpickler(pickle.Unpickler):

    def find_class(self, module, name):
        # Only allow safe classes from builtins.
        if module == "builtins" and name in safe_builtins:
            return getattr(builtins, name)
        # Forbid everything else.
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
                                     (module, name))

def restricted_loads(s):
    """Helper function analogous to pickle.loads()."""
    return RestrictedUnpickler(io.BytesIO(s)).load()

हमारे unpickler काम करने का एक नमूना उपयोग इरादा है:

>>> restricted_loads(pickle.dumps([1, 2, range(15)]))
[1, 2, range(0, 15)]
>>> restricted_loads(b"cos\nsystem\n(S'echo hello world'\ntR.")
Traceback (most recent call last):
  ...
pickle.UnpicklingError: global 'os.system' is forbidden
>>> restricted_loads(b'cbuiltins\neval\n'
...                  b'(S\'getattr(__import__("os"), "system")'
...                  b'("echo hello world")\'\ntR.')
Traceback (most recent call last):
  ...
pickle.UnpicklingError: global 'builtins.eval' is forbidden

जैसा कि हमारे उदाहरणों से पता चलता है, आपको इस बात से सावधान रहना होगा कि आप क्या अप्रकाशित होने की अनुमति देते हैं। इसलिए यदि सुरक्षा एक चिंता का विषय है, तो आप वैकल्पिक विकल्पों पर विचार करना चाह सकते हैं जैसे मार्शलींग एपीआई xmlrpc.client या तीसरे पक्ष के समाधान।

प्रदर्शन

अचार प्रोटोकॉल के हाल के संस्करणों (प्रोटोकॉल 2 और ऊपर से) में कई सामान्य सुविधाओं और अंतर्निहित प्रकारों के लिए कुशल बाइनरी एन्कोडिंग की सुविधा है। साथ ही, pickle मॉड्यूल में C में लिखा हुआ पारदर्शी अनुकूलक है।

उदाहरण

सरल कोड के लिए, फ़ंक्शन dump() और load() फ़ंक्शन का उपयोग करें ।

import pickle

# An arbitrary collection of objects supported by pickle.
data = {
    'a': [1, 2.0, 3, 4+6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('data.pickle', 'wb') as f:
    # Pickle the 'data' dictionary using the highest protocol available.
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

निम्न उदाहरण परिणामस्वरूप पिक किए गए डेटा को पढ़ता है।

import pickle

with open('data.pickle', 'rb') as f:
    # The protocol version used is detected automatically, so we do not
    # have to specify it.
    data = pickle.load(f)

यह भी देखें

Module copyreg
एक्सटेंशन प्रकारों के लिए अचार इंटरफ़ेस निर्माता पंजीकरण।
Module pickletools
अचार वाले डेटा के साथ काम करने और विश्लेषण करने के लिए उपकरण।
Module shelve
वस्तुओं के अनुक्रमित डेटाबेस; का उपयोग करता है pickle
Module copy
उथली और गहरी वस्तु की नकल।
Module marshal
निर्मित प्रकारों का उच्च प्रदर्शन क्रमिकता।

फुटनोट

[1] marshal मॉड्यूल के साथ इसे भ्रमित न करें
[2] यही कारण है कि lambda कार्यों को चुना नहीं जा सकता है: सभी lambda फ़ंक्शन समान नाम साझा करते हैं <lambda> :।
[3] उठाए गए अपवाद की संभावना एक ImportError या होगी, AttributeError लेकिन यह कुछ और हो सकती है।
[4] copy मॉड्यूल उथले और गहरी नकल के संचालन के लिए इस प्रोटोकॉल का उपयोग करता है।
[5] अल्फ़ान्यूमेरिक वर्णों पर सीमा इस तथ्य के कारण है कि प्रोटोकॉल 0 में लगातार आईडी, न्यूलाइन वर्ण द्वारा सीमांकित हैं। इसलिए यदि लगातार ID में किसी भी प्रकार के नए वर्ण आते हैं, तो परिणामस्वरूप अचार अपठनीय हो जाएगा।

Original text