2016-04-17 8 views
5

documentation for Pickle विशेष रूप से कहते हैं:पिकल कॉलिंग क्यों नहीं है __new__ प्रलेखन की तरह कहते हैं?

एक नई शैली वर्ग सी के उदाहरण का उपयोग कर बनाई गई हैं:

obj = C.__new__(C, *args) 

इस का लाभ लेने के प्रयास कर रहा है, मैं एक सिंगलटन कोई उदाहरण के साथ जिम्मेदार बताते हैं बनाया है या विधियां:

class ZeroResultSentinel(object): 
    instance = None 
    def __new__(cls, *args): 
     if not cls.instance: 
      cls.instance = super(ZeroResultSentinel, cls).__new__(cls, *args) 
     return cls.instance 

(इस वर्ग का उपयोग कैशिंग परत में किया जाता है ताकि परिणाम नतीजे न हो एम कैश में कुछ नहीं।)

सिंगलटन बहुत अच्छा काम करता है (ZeroResultSentinel() पर प्रत्येक कॉल मेमोरी में एक ही उदाहरण में परिणाम देता है, और ZeroResultSentinel() == ZeroResultSentinel()True का मूल्यांकन करता है)। और मैं अचार और त्रुटियों के बिना उदाहरण को अनपिक कर सकता हूं। हालांकि, जब मैं इसे अनपिक करता हूं, तो मुझे एक अलग उदाहरण मिलता है। तो मैंने __new__ के भीतर ब्रेकपॉइंट रखा। जब भी मैं ZeroResultSentinel() पर कॉल करता हूं तो मैंने ब्रेकपॉइंट मारा, लेकिन जब मैं एक मसालेदार ZeroResultSentinel को अनपिक करता हूं तो मैं ब्रेकपॉइंट नहीं मारता। यह दस्तावेज़ीकरण के प्रत्यक्ष विरोधाभास में है। तो क्या मैं कुछ गलत कर रहा हूं, या दस्तावेज गलत है?

+1

आप कौन सा अचार प्रोटोकॉल निर्दिष्ट कर रहे हैं? – user2357112

उत्तर

3

प्रलेखन वास्तव में यह स्पष्ट नहीं है, लेकिन अपने __new__ विधि केवल अचार प्रोटोकॉल 2 के लिए और ऊपर उपयोग किया जाएगा: यदि आप ऐसा '

>>> class Foo(object): 
...  def __new__(cls): 
...   print "New" 
...   return object.__new__(cls) 
... 
>>> foo = Foo() 
New 
>>> pickle.loads(pickle.dumps(foo, protocol=0)) 
<__main__.Foo object at 0x00000000025E9A20> 
>>> pickle.loads(pickle.dumps(foo, protocol=2)) 
New 
<__main__.Foo object at 0x00000000022A3F60> 

अजगर 2 पर, डिफ़ॉल्ट प्रोटोकॉल 0 है, डिफ़ॉल्ट का उपयोग कर रहे हैं, आपको इसे बदलना होगा।

+0

अच्छा, shucks। मैंने पुष्टि की है कि इसे ठीक करता है। लेकिन हम Django के एक बहुत पुराने संस्करण पर हैं जो कैश बैकएंड के लिए प्रोटोकॉल निर्दिष्ट नहीं करता है, इसलिए अपग्रेड किए जाने तक मैं इसके बारे में कुछ भी नहीं कर सकता। '__new__' का उपयोग न करने पर पहले _does_ अचार पहले प्रोटोकॉल में एक उदाहरण कैसे बनाते हैं? –

+0

सुधार: इसका Django से कोई लेना देना नहीं है। विन्यास सेटिंग्स को pickle.HIGHEST_PROTOCOL, 'हमारे कैश बैकएंड इस काम करने के लिए पाने के लिए: हम सिर्फ इतना है कि एक प्रोटोकॉल –

+0

मैं' 'pickleProtocol' जोड़ने के लिए सक्षम था निर्दिष्ट किए बिना अचार करता है एक कैश पुस्तकालय की दया पर कर रहे हैं। मदद के लिए बहुत बहुत धन्यवाद! (मैं अभी भी उत्सुक हूँ, अगर आप एक मिनट है, _how_ अचार '__new__' बुला बिना एक वस्तु का एक उदाहरण बना सकते हैं।) –

संबंधित मुद्दे