2013-05-18 9 views
19

मैं इस तरह की वस्तुओं की एक सरणी अचार के लिए है:अजगर, cPickle, अचार बनाने लैम्ब्डा कार्यों

import cPickle as pickle 
from numpy import sin, cos, array 
tmp = lambda x: sin(x)+cos(x) 
test = array([[tmp,tmp],[tmp,tmp]],dtype=object) 
pickle.dump(test, open('test.lambda','w')) 

और यह निम्न त्रुटि देता है:

TypeError: can't pickle function objects 

वहाँ कि चारों ओर एक तरीका है?

+0

ऐसा करने के लिए एक अजीब चीज़ की तरह लगता है। उपयोग-केस क्या है? – Aya

+0

@Aya lamdify SymPy में lambda कार्यों को बनाने के लिए बहुत सुविधाजनक बनाता है। और मैं साइथन का उपयोग करके उनका मूल्यांकन करना चाहता हूं। आप [इस जानकारी को और जानकारी के लिए देख सकते हैं] (http://stackoverflow.com/questions/16295140/numerical-integration-over-a-matrix-of-functions-sympy-and-scipy) –

+1

ठीक है, मैं नहीं करता साइथन के बारे में बहुत कुछ नहीं पता, लेकिन मार्टिजन का समाधान केवल तभी काम करेगा जब साइथन के लिए पाइथन फ़ाइल आयात करना संभव हो, जिसमें 'tmp (x)' फ़ंक्शन परिभाषित किया गया था। – Aya

उत्तर

22

बिल्ट-इन अचार मॉड्यूल कई प्रकार के पायथन ऑब्जेक्ट्स (लैम्ब्डा फ़ंक्शन, नेस्टेड फ़ंक्शंस और कमांड लाइन पर परिभाषित फ़ंक्शंस सहित) को क्रमबद्ध करने में असमर्थ है।

picloud पैकेज में एक और मजबूत पिकलर शामिल है, जो लैम्ब्डा कार्यों को उठा सकता है।

from pickle import dumps 
f = lambda x: x * 5 
dumps(f) # error 
from cloud.serialization.cloudpickle import dumps 
dumps(f) # works 

PiCloud-धारावाहिक वस्तुओं सामान्य अचार/cPickle load और loads कार्यों का उपयोग कर डी-धारावाहिक जा सकता है।

Dill भी इसी तरह की सुविधा

>>> import dill   
>>> f = lambda x: x * 5 
>>> dill.dumps(f) 
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_unmarshal\nq\x01Uec\x01\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00C\x00\x00\x00s\x08\x00\x00\x00|\x00\x00d\x01\x00\x14S(\x02\x00\x00\x00Ni\x05\x00\x00\x00(\x00\x00\x00\x00(\x01\x00\x00\x00t\x01\x00\x00\x00x(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x08\x00\x00\x00<lambda>\x01\x00\x00\x00s\x00\x00\x00\x00q\x02\x85q\x03Rq\x04c__builtin__\n__main__\nU\x08<lambda>q\x05NN}q\x06tq\x07Rq\x08.' 
+0

धन्यवाद! picloud पैकेज के साथ यह काम किया! डिल मैंने अभी तक परीक्षण नहीं किया है ... बनाया गया अचार पारंपरिक अचार या सीपीकल मॉड्यूल का उपयोग करके लोड किया जा सकता है –

+1

क्या मल्टीप्रोसेसिंग लाइब्रेरी के साथ इस पिकर का उपयोग करने का कोई तरीका है? –

+0

उत्तर है: http://stackoverflow.com/questions/19984152/what-can-multiprocessing-and-dill-do-together –

9

आप के बजाय एक वास्तविक समारोह का उपयोग करना होगा, एक है कि देश में लाने योग्य है (एक और समारोह के अंदर से नहीं लगाए गए):

import cPickle as pickle 
from numpy import sin, cos, array 
def tmp(x): 
    return sin(x)+cos(x) 
test = array([[tmp,tmp],[tmp,tmp]],dtype=object) 
pickle.dump(test, open('test.lambda','w')) 

समारोह वस्तु अभी भी एक lambda अभिव्यक्ति द्वारा उत्पादित किया जा सकता है, लेकिन केवल आप अगर बाद में जिसके परिणामस्वरूप समारोह वस्तु एक ही नाम दे: केवल

tmp = lambda x: sin(x)+cos(x) 
tmp.__name__ = 'tmp' 
test = array([[tmp, tmp], [tmp, tmp]], dtype=object) 

क्योंकि pickle भंडार मॉड्यूल और एक समारोह वस्तु के लिए नाम; उपरोक्त उदाहरण में, tmp.__module__ और tmp.__name__ अब उस स्थान पर वापस इंगित करें जहां एक ही ऑब्जेक्ट अनपिकलिंग के बाद फिर से मिल सकता है।

+0

मुझे लगता है कि इस तरह के उत्तर का उपयोग सी आधारित मॉड्यूल के अंतर्निर्मित कार्यों पर नहीं किया जा सकता है * (भले ही ᴏꜱ और आर्किटेक्चर वही रहें) *। – user2284570

+0

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

+0

तो क्या आपका मतलब है कि इसे सहेजना संभव है लेकिन कुछ निष्पादन योग्य पुनर्स्थापित नहीं करना है? मुझे केवल बहाल करने में दिलचस्पी है * (डंप बनाना पाइथन में नहीं किया जाना चाहिए) *। मुझे परवाह नहीं है * क्या उपयोग किया जाता है * (मार्शल या सीपीकल) * जब तक कोई तीसरे पक्ष के मॉड्यूल का उपयोग नुकीले के अपवाद के साथ किया जाता है। – user2284570

5

एक और उपाय है प्रदान करता है: आप के रूप में तार, अचार/बिना अचार कार्यों को परिभाषित तो eval, पूर्व का उपयोग करें:

import cPickle as pickle 
from numpy import sin, cos, array 
tmp = "lambda x: sin(x)+cos(x)" 
test = array([[tmp,tmp],[tmp,tmp]],dtype=object) 
pickle.dump(test, open('test.lambda','w')) 
mytmp = array([[eval(x) for x in l] for l in pickle.load(open('test.lambda','r'))]) 
print mytmp 
# yields : [[<function <lambda> at 0x00000000033D4DD8> 
#   <function <lambda> at 0x00000000033D4E48>] 
#   [<function <lambda> at 0x00000000033D4EB8> 
#   <function <lambda> at 0x00000000033D4F28>]] 

यह और अधिक सुविधाजनक हो सकता है अन्य समाधानों के लिए क्योंकि मसालेदार प्रतिनिधित्व बाहरी निर्भरताओं का उपयोग किए बिना पूरी तरह निहित होगा।

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