2010-05-28 28 views
9

में एक अनबाउंड विधि उठाकर मैं पायथन 3.x में एक अनबाउंड विधि चुनना चाहता हूं। मुझे यह त्रुटि मिल रही है:पायथन 3

>>> class A: 
...  def m(self): 
...   pass 
>>> import pickle 
>>> pickle.dumps(A.m) 
Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    pickle.dumps(A.m) 
    File "C:\Python31\lib\pickle.py", line 1358, in dumps 
    Pickler(f, protocol, fix_imports=fix_imports).dump(obj) 
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed 

क्या किसी के पास इसका अनुभव है?


नोट: पायथन 2.x में डिफ़ॉल्ट रूप से अनबाउंड विधियों को चुनना भी असंभव है; मैं इसे कुछ अजीब तरीके से करने में कामयाब रहा, मुझे समझ में नहीं आया: मैंने मेथड टाइप क्लास के लिए copy_reg मॉड्यूल के साथ एक रेड्यूसर लिखा, जिसमें बाध्य और अनबाउंड दोनों विधियां शामिल हैं। लेकिन reducer केवल बाध्य विधि के मामले को हल किया, क्योंकि यह my_method.im_self पर निर्भर था। रहस्यमय रूप से यह पाइथन 2.x को अनबाउंड विधियों को चुनने में सक्षम होने के कारण भी है। यह पायथन 3.x पर नहीं होता है।

उत्तर

7

यह सीधे नहीं किया जा सकता क्योंकि पायथन में 3 अनबाउंड विधि प्रकार चला गया है: यह सिर्फ एक समारोह है:,

>>> print (type (A.m)) 
<class 'function'> 

अजगर कार्यों एक वर्ग के लिए बाध्य नहीं कर रहे हैं तो यह बता पाना असंभव है क्या वर्ग A.m केवल अभिव्यक्ति परिणाम देखकर संबंधित है।

वास्तव में क्या आप की जरूरत के आधार पर, अचार बनाने/(क्लास, मेथड-नाम) के एक टपल unpickling काफी अच्छा हो सकता है:

>>> print (pickle.loads (pickle.dumps ((A, 'm')))) 
... (<class '__main__.A'>, 'm') 

आप बस getattr() का उपयोग करके यहां से विधि (समारोह) प्राप्त कर सकते हैं :

>>> cls, method = pickle.loads (pickle.dumps ((A, 'm'))) 
>>> print (getattr (cls, method)) 
... <function m at 0xb78878ec> 
+1

क्या आप कह रहे हैं कि पाइथन 3 पर, एक अनबाउंड विधि दी गई है, यह जानने का कोई तरीका नहीं है कि यह विधि कहां परिभाषित की गई थी? –

+4

हां। दो वर्गों की घोषणा करने का प्रयास करें और एक विधि को एक से दूसरे में असाइन करें ('बीएम = एएम')। फिर 'बीएम' और 'एएम' बराबर होंगे (वास्तव में, समान), इसलिए यह बताना संभव नहीं है कि आपने 'बी' या 'ए' में विधि को देखा है या नहीं। – doublep