2010-01-12 11 views
14

मैं एक वर्ग (नीचे) है:मैं इस ऑब्जेक्ट को क्यों नहीं उठा सकता?

class InstrumentChange(object): 
    '''This class acts as the DTO object to send instrument change information from the 
     client to the server. See InstrumentChangeTransport below 
    ''' 
    def __init__(self, **kwargs): 
     self.kwargs = kwargs 
     self._changed = None 

    def _method_name(self, text): 
     return text.replace(' ','_').lower() 

    def _what_changed(self): 
     ''' Denotes the column that changed on the instrument returning the column_name of what changed.''' 
     if not self._changed: 
      self._changed = self._method_name(self.kwargs.pop('What Changed')) 

     return self._changed 

    def __getattr__(self, attr): 
     for key in self.kwargs.iterkeys(): 
      if self._method_name(key) == attr: 
       return self.kwargs[key] 

    def __str__(self): 
     return "Instrument:%s" % self.kwargs 

    __repr__ = __str__ 

    what_changed = property(_what_changed) 

मैं निम्नलिखित परीक्षण चलाते हैं:

def test_that_instrumentchangetransport_is_picklable(self): 
     test_dict = {'Updated': 'PAllum', 'Description': 'BR/EUR/BRAZIL/11%/26/06/2017/BD', 
     'Ask Q': 500, 'Bbg': 'On', 'C Bid': 72.0, 'Benchmark': 'NL/USD/KKB/7.000%/03/11/2009/BD', 
     'ISIN': 'XS0077157575', 'Bid YTM': 0.0, 'Bid Q': 100, 'C Ask': 72.25, 'Ask YTM': 0.0, 'Bid ASW': 0.0, 
     'Position': 1280000, 'What Changed': 'C Bid', 'Ask ASW': 0.0} 
     ins_change = InstrumentChangeTransport(**test_dict) 
     assert isinstance(ins_change, InstrumentChangeTransport) 

     # Create a mock filesystem object 
     file = open('testpickle.dat', 'w') 
     file = Mock() 
     pickle.dump(ins_change, file) 

मैं:

Traceback (most recent call last): 
    File "c:\python23\lib\site-packages\nose-0.11.0-py2.3.egg\nose\case.py", line 183, in runTest 
    self.test(*self.arg) 
    File "C:\Code\branches\demo\tests\test_framework.py", line 142, in test_that_instrumentchangetransport_is_picklable 
    pickle.dump(ins_change, file) 
    File "C:\Python23\Lib\copy_reg.py", line 83, in _reduce_ex 
    dict = getstate() 
TypeError: 'NoneType' object is not callable 

मैं अचार डॉक्स देखा है, लेकिन मुझे काफी कुछ नहीं मिला है।

कोई विचार?

बेन

+1

एक साइड नोट के रूप में: 'key.kwargs.iterkeys() में कुंजी कुंजी के माध्यम से कुंजी और खोज उत्पन्न करती है। बेहतर उपयोग 'self.kwargs' में, जो हैशटेबल लुकअप (तेज़) करने का प्रयास करता है। – ebo

+1

कुछ डिबगिंग करने में सहायता मांगते समय, यह समस्या को पुन: उत्पन्न करने के लिए पर्याप्त कोड प्रदान करने में मदद करता है। यह आपके द्वारा पोस्ट किए गए कोड से अप्रासंगिक सब कुछ हटाने में और भी मदद करता है। –

उत्तर

29

आपके कोड में कई मामूली "पक्ष" मुद्दे हैं: परीक्षण में उपयोग किए जाने वाले वर्ग नाम में 'परिवहन' की अचानक उपस्थिति (यह कक्षा का नाम नहीं है जिसे आप परिभाषित कर रहे हैं), अंतर्निहित पर संदिग्ध ट्रैम्पलिंग पहचानकर्ता file स्थानीय चर के रूप में (ऐसा न करें - यह यहां चोट नहीं पहुंचाता है, लेकिन अंतर्निर्मित पहचानकर्ताओं पर ट्रामलिंग की आदत एक दिन रहस्यमय बग का कारण बनती है), Mock के दुरुपयोग जो पहले से ही नोट किया गया है, अचार, grungiest पिकलिंग प्रोटोकॉल और पिकल फ़ाइल के लिए बाइनरी के बजाय पाठ का डिफ़ॉल्ट उपयोग।

हालांकि, दिल में, जैसा कि @coonj कहते हैं, राज्य नियंत्रण की कमी है। एक "सामान्य" वर्ग की आवश्यकता नहीं होती है (क्योंकि self.__dict__ राज्य नियंत्रण और अन्य विशिष्टताओं के बिना कक्षाओं में डिफ़ॉल्ट रूप से मसालेदार और अनप्लिक हो जाता है) - लेकिन चूंकि आप __getattr__ ओवरराइड कर रहे हैं जो आपकी कक्षा पर लागू नहीं होता है। तुम सिर्फ दो और बहुत ही सरल तरीकों की जरूरत है:

def __getstate__(self): return self.__dict__ 
def __setstate__(self, d): self.__dict__.update(d) 

जो मूल रूप से pickle बता सिर्फ एक सामान्य की तरह अपनी कक्षा के इलाज के लिए, __getattr__ के अस्तित्व के बावजूद, उदाहरण के राज्य का प्रतिनिधित्व है के रूप में self.__dict__ लेने।

+0

यह सत्यापित करने के लिए धन्यवाद - 100+ विचार और आप मेरे साथ सहमत होने वाले पहले व्यक्ति हैं ...मैं चिंतित हो रहा था –

+4

@coonj, मुझे लगता है कि लोगों को मुश्किल समय लगता है कि क्यों उन्हें राज्य-हैंडलिंग विधियों को परिभाषित करने की आवश्यकता होनी चाहिए क्योंकि आम तौर पर उनकी आवश्यकता नहीं होती है (और कहीं भी यह स्पष्ट रूप से दस्तावेज नहीं है कि '__getattr__' उन्हें आवश्यक बनाता है)। –

+0

धन्यवाद एलेक्स और कोंज, यह परीक्षण एक समस्या को फिर से बनाना था जो एक मोड़ वाले पीबी सत्र पर एक दूरस्थ वस्तु भेजने के साथ था। यह सब कुछ हैम मुट्ठी है - हालांकि मैं वास्तव में आपके अंक की सराहना करता हूं। मेरी पायथन सीखने ने अभी कुछ क्लिक किए हैं। आपकी मदद के लिए धन्यवाद। बेन –

2
file = open('testpickle.dat', 'w') 
    file = Mock() 

आप यहाँ खोला फ़ाइल के संदर्भ में खो रहे हैं। क्या यह एक समस्या हो सकती है?

+0

यह समस्या का संभावित कारण प्रतीत होता है। – jathanism

6

यह विफल रहा है क्योंकि यह आपके ऑब्जेक्ट के लिए __getstate__() नहीं ढूंढ सकता है। ऑब्जेक्ट को अचार/अनपिक करने का तरीका निर्धारित करने के लिए अचार की आवश्यकता होती है। आपको बस __getstate__() और __setstate__() विधियों की आवश्यकता है।

डॉक्स में TextReader उदाहरण देखें: http://docs.python.org/library/pickle.html

अद्यतन: मैं बस sourceforge page for the Mock module, को देखा और मैं तुम्हें भी इसे गलत तरीके से उपयोग कर रहे हैं लगता है। आप फ़ाइल-ऑब्जेक्ट का मज़ाक उड़ा रहे हैं, लेकिन जब अचार इसे पढ़ने की कोशिश करता है, तो उसे कुछ भी वापस नहीं मिलेगा, इसलिए getattr() कोई भी नहीं देता है।

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