2009-08-28 11 views
6

में सुन्दरता अपमानजनक अचार बनानेअजगर

मैं अजगर में वस्तुओं अचार के लिए एक शान से अपमानजनक तरीके से चाहते हैं (आप कुछ पृष्ठभूमि के लिए this प्रश्न पढ़ सकते हैं)। क्योंकि यह मुख्य उद्देश्य की एक निश्चित उप वस्तु अचार नहीं कर सकते

जब एक वस्तु नमकीन बनाना, चलो यह मुख्य उद्देश्य कॉल, कभी कभी पिकलर एक अपवाद को जन्म देती है। उदाहरण के लिए, मुझे एक त्रुटि मिली है जो "मॉड्यूल ऑब्जेक्ट्स नहीं उठा सकता है।" ऐसा इसलिए है क्योंकि मैं मुख्य वस्तु से मॉड्यूल का संदर्भ दे रहा हूं।

मैं मैं एक छोटे से कुछ एक मुखौटा है कि मॉड्यूल के गुण होते हैं साथ कि मॉड्यूल को बदलने के लिए ऊपर लिख सकते हैं पता है, लेकिन है कि अपने स्वयं के मुद्दों (1) होगा।

तो क्या मैं चाहूँगा एक अचार समारोह है कि स्वचालित रूप से मॉड्यूल की जगह (और किसी भी अन्य मुश्किल से अचार वस्तुओं) अग्रभाग कि उनकी विशेषताओं को शामिल के साथ है। यह एक आदर्श पिकलिंग का उत्पादन नहीं कर सकता है, लेकिन कई मामलों में यह पर्याप्त होगा।

वहाँ इस तरह कुछ भी है? क्या किसी को यह पता है कि इस तक कैसे पहुंचे?


(1) एक मुद्दा यह होगा कि मॉड्यूल इसके भीतर से अन्य मॉड्यूल का संदर्भ दे सकता है।

+1

जावा बीन्स .. पायथन पिकल्स .. मैं इसके साथ आने वाले नरों को थ्रॉटल करना चाहता हूं cutesy stuff –

उत्तर

0

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

class PickleableModuleWrapper(object): 
    def __init__(self, module): 
     # make a copy of the module's namespace in this instance 
     self.__dict__ = dict(module.__dict__) 
     # remove anything that's going to give us trouble during pickling 
     self.remove_unpickleable_attributes() 

    def remove_unpickleable_attributes(self): 
     for name, value in self.__dict__.items(): 
      try: 
       pickle.dumps(value) 
      except Exception: 
       del self.__dict__[name] 

import pickle 
p = pickle.dumps(PickleableModuleWrapper(pickle)) 
wrapped_mod = pickle.loads(p) 
0

हम्म, ऐसा कुछ?

import sys 

attribList = dir(someobject) 
for attrib in attribList: 
    if(type(attrib) == type(sys)): #is a module 
     #put in a facade, either recursively list the module and do the same thing, or just put in something like str('modulename_module') 
    else: 
     #proceed with normal pickle 
जाहिर

, यह एक reimplemented डंप विधि के साथ अचार वर्ग का एक विस्तार में जाना होगा ...

3

आप तय है और इसके क्रियान्वयन कैसे किसी भी पूर्व-unpicklable प्रकार मसालेदार हो जाता है और unpickled कर सकते हैं: देखने के मानक पुस्तकालय मॉड्यूल copy_reg (पायथन 3. * में copyreg नाम दिया)।

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

आमतौर पर, टपल तुम वापस 2 आइटम नहीं है। प्रतिदेय एक "सुरक्षित निर्माता" के रूप में पंजीकृत होना जरूरी है या समतुल्य एक सही मूल्य के साथ एक विशेषता __safe_for_unpickling__ है। उन वस्तुओं मसालेदार किया जाएगा, और unpickling समय में प्रतिदेय दिए गए तर्कों के साथ बुलाया जाएगा और बिखरा हुआ वस्तु लौट जाना चाहिए।

उदाहरण के लिए

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

>>> import sys, pickle, copy_reg 
>>> def savemodule(module): 
... return __import__, (module.__name__,) 
... 
>>> copy_reg.pickle(type(sys), savemodule) 
>>> s = pickle.dumps(sys) 
>>> s 
"c__builtin__\n__import__\np0\n(S'sys'\np1\ntp2\nRp3\n." 
>>> z = pickle.loads(s) 
>>> z 
<module 'sys' (built-in)> 

मैं अचार के पुराने ढंग का ASCII प्रपत्र का उपयोग कर रहा है, ताकि s, स्ट्रिंग अचार युक्त, आसान जांच करने के लिए है: यह कॉल करने के लिए unpickling निर्देश देता में निर्मित आयात समारोह, के साथ स्ट्रिंग sys अपने एकमात्र तर्क के रूप में। और z दिखाता है कि यह वास्तव में वांछित के रूप में, अनपिकलिंग के परिणामस्वरूप अंतर्निहित sys मॉड्यूल को वापस देता है।

अब, आपको __import__ की तुलना में चीजों को थोड़ा अधिक जटिल बनाना होगा (आपको गतिशील परिवर्तनों को सहेजने और पुनर्स्थापित करने, घोंसला वाले नामस्थान आदि को नेविगेट करने, और इस प्रकार आपको भी करना होगा) copy_reg.constructor पर कॉल करें (मॉड्यूल-सेविंग फ़ंक्शन जो आपके अन्य फ़ंक्शन को लौटाता है (और, यदि एक अलग रन में भी है, तो आप उन फ़ंक्शंस को अनपिक करने से पहले जो फ़ंक्शन का उपयोग करके बनाते हैं) से पहले कॉल करें। लेकिन मुझे उम्मीद है कि यह साधारण मामलों यह दिखाने में मदद करता है कि इसमें वास्तव में कुछ भी नहीं है जो कि "आंतरिक रूप से जटिल" है! -

+0

@ एलेक्स मार्टेलि: जब मैं copy_reg.pickle का उपयोग करता हूं, तो यह परिवर्तन किस क्षेत्र में प्रासंगिक होगा? मैं चाहता हूं कि लोग बिना किसी सिस्टम वैल्यू को बदलने के मेरे काम को आयात करने में सक्षम हों जो उनके प्रोग्राम को बर्बाद कर सकता है। –

+0

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

+0

@ एलेक्स मार्टेलि: लेकिन अगर वे एक ही मुद्दे में और परिभाषित मॉड्यूल को अलग तरीके से चुनते हैं, तो हमें एक समस्या होगी। मैं विनम्र होने और सिस्टम राज्य को बदलने में विश्वास करता हूं। मेरा मानना ​​है कि जब आप पाइथन में कुछ मॉड्यूल आयात करते हैं तो आपको इसके बारे में चिंता करने की ज़रूरत नहीं है कि आप अपने सिस्टम के ग्लोबल्स से गड़बड़ कर रहे हैं, और यह उन उपकरणों के लिए महत्वपूर्ण है जो आपको अपने मॉड्यूल में इस तरह की "अयोग्यता" से बचने की अनुमति देते हैं। –