2010-04-13 33 views
5

क्या कक्षा परिभाषा को चुनने का कोई तरीका है?कक्षा परिभाषा को चुनना

मैं क्या करना चाहता हूं परिभाषा (जिसे गतिशील रूप से बनाया जा सकता है) पिकल है, और फिर इसे एक टीसीपी कनेक्शन पर भेज दें ताकि दूसरे सिरे पर एक उदाहरण बनाया जा सके।

मैं समझता हूं कि निर्भरताएं हो सकती हैं, जैसे कि मॉड्यूल और ग्लोबल वैरिएबल जैसे वर्ग निर्भर करता है। मैं इन्हें पिकलिंग प्रक्रिया में भी बंडल करना चाहता हूं, लेकिन मैं निर्भरताओं को स्वचालित रूप से पहचानने के बारे में चिंतित नहीं हूं क्योंकि यह ठीक है अगर उपयोगकर्ता उन्हें निर्दिष्ट करने के लिए ऑनस पर है।

+0

मैं इस जो पूरे दुभाषिया राज्य अचार पाया कक्षा परिभाषाओं को भी मसालेदार लगते हैं ... – Giorgio

उत्तर

2

अलास, सीधे नहीं। आप class कथन, या बाइटकोड फ़ॉर्म का स्ट्रिंग फॉर्म भेज सकते हैं, और इसे प्राप्त करने वाले exec के साथ "रीहाइड्रेट" कर सकते हैं।

+0

क्या आप कक्षा विवरण वाले .py या .pyc फ़ाइलों को भेजने का जिक्र कर रहे हैं? – Giorgio

+1

@ जॉर्जियो, आपको '.py' या '.pyc' फ़ाइल के _all_ को भेजने की आवश्यकता नहीं है, केवल कक्षा का स्रोत (जैसा कि http://docs.python.org/library/inspect द्वारा पहचाना गया है .html? # inspect.getsource) या इसके 'compile'd फॉर्म। –

1

प्रलेखन यह समझाने का एक बहुत अच्छा काम करता है कि क्या उठाया जा सकता है और क्यों नहीं किया जा सकता है, और ऐसा क्यों है।

http://docs.python.org/library/pickle.html#what-can-be-pickled-and-unpickled

मूल रूप से, अगर वर्ग या मॉड्यूल नाम से आयात योग्य है जब यह unpickled हो जाता है, यह काम करना चाहिए, जब तक कि आप अब और जब आप इसे unpickle के बीच अपनी कक्षा परिभाषा को बदलने की योजना है। नीचे वर्ग परिभाषा में, केवल वर्ग का नाम "टेस्ट" है, और विधि का नाम "mymethod" चुना जाएगा। यदि आप कक्षा परिभाषा को चुनते हैं, तो परिभाषा को बदलें ताकि attr एक अलग मान हो, और mymethod कुछ पूरी तरह से अलग करता है, अचार नई परिभाषा उठाएगा।

class Test(object): 
    attr = 5 

    def mymethod(self, arg): 
     return arg 
1

आप dill उपयोग करते हैं, यह __main__ के इलाज के लिए जैसे कि वह (अधिकांश भाग के लिए) एक अजगर मॉड्यूल थे सक्षम बनाता है। इसलिए, आप अंतःक्रियात्मक परिभाषित कक्षाओं को क्रमबद्ध कर सकते हैं, और इसी तरह। dill भी (डिफ़ॉल्ट रूप से) अचार के हिस्से के रूप में कक्षा परिभाषा को परिवहन कर सकता है।

>>> class MyTest(object): 
... def foo(self, x): 
...  return self.x * x 
... x = 4 
... 
>>> f = MyTest() 
>>> import dill 
>>> 
>>> with open('test.pkl', 'wb') as s: 
... dill.dump(f, s) 
... 
>>> 

फिर दुभाषिया को बंद करें, और फ़ाइल test.pkl टीसीपी पर भेजें। आपकी रिमोट मशीन पर, अब आप क्लास इंस्टेंस प्राप्त कर सकते हैं।

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import dill 
>>> with open('test.pkl', 'rb') as s: 
... f = dill.load(s) 
... 
>>> f 
<__main__.MyTest object at 0x1069348d0> 
>>> f.x 
4 
>>> f.foo(2) 
8 
>>>    

लेकिन कक्षा परिभाषा कैसे प्राप्त करें? तो यह वही नहीं है जो आप चाहते थे। हालांकि, निम्नलिखित है।

>>> class MyTest2(object): 
... def bar(self, x): 
...  return x*x + self.x 
... x = 1 
... 
>>> import dill 
>>> with open('test2.pkl', 'wb') as s: 
... dill.dump(MyTest2, s) 
... 
>>> 

फिर फ़ाइल भेजने के बाद ... आप कक्षा परिभाषा प्राप्त कर सकते हैं।

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import dill 
>>> with open('test2.pkl', 'rb') as s: 
... MyTest2 = dill.load(s) 
... 
>>> print dill.source.getsource(MyTest2) 
class MyTest2(object): 
    def bar(self, x): 
    return x*x + self.x 
    x = 1 

>>> f = MyTest2() 
>>> f.x 
1 
>>> f.bar(4) 
17 

तो, dill भीतर, वहाँ dill.source है, और है कि तरीकों कि कार्यों और वर्गों के निर्भरता का पता लगा सकते हैं, और उन्हें अचार (अधिकांश भाग के लिए) के साथ साथ ले गया है।

>>> def foo(x): 
... return x*x 
... 
>>> class Bar(object): 
... def zap(self, x): 
...  return foo(x) * self.x 
... x = 3 
... 
>>> print dill.source.importable(Bar.zap, source=True) 
def foo(x): 
    return x*x 
def zap(self, x): 
    return foo(x) * self.x 

तो है कि "सही" नहीं है (या शायद नहीं क्या उम्मीद है) ... लेकिन यह एक गतिशील बनाया विधि के लिए कोड को क्रमानुसार करता है और यह निर्भरता है। आपको बस बाकी वर्ग नहीं मिलता है - लेकिन इस मामले में बाकी वर्ग की आवश्यकता नहीं है।

यदि आप सब कुछ प्राप्त करना चाहते हैं, तो आप बस पूरे सत्र को चुन सकते हैं।

>>> import dill 
>>> def foo(x): 
... return x*x 
... 
>>> class Blah(object): 
... def bar(self, x): 
...  self.x = (lambda x:foo(x)+self.x)(x) 
... x = 2 
... 
>>> b = Blah() 
>>> b.x 
2 
>>> b.bar(3) 
>>> b.x 
11 
>>> dill.dump_session('foo.pkl') 
>>> 

फिर दूरस्थ मशीन पर ...

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import dill 
>>> dill.load_session('foo.pkl') 
>>> b.x 
11 
>>> b.bar(2) 
>>> b.x 
15 
>>> foo(3) 
9 

अंत में, आप के लिए पारदर्शिता के साथ आपको pathos.pp या ppft है, जो एक दूसरे अजगर सर्वर से वस्तुओं जहाज की क्षमता (एक दूरस्थ मशीन पर) प्रदान करने या अजगर इस्तेमाल कर सकते हैं "किया" जा करने के लिए यदि आप परिवहन चाहते हैं, प्रक्रिया। वे हुड के नीचे dill का उपयोग करते हैं, और बस तार भर में कोड पास करते हैं।

>>> class More(object): 
... def squared(self, x): 
...  return x*x 
... 
>>> import pathos 
>>> 
>>> p = pathos.pp.ParallelPythonPool(servers=('localhost,1234',)) 
>>> 
>>> m = More() 
>>> p.map(m.squared, range(5)) 
[0, 1, 4, 9, 16] 

servers तर्क वैकल्पिक है, और यहाँ सिर्फ बंदरगाह 1234 पर स्थानीय मशीन से कनेक्ट कर रहा है ... लेकिन अगर आप के बजाय (या के रूप में अच्छी) रिमोट मशीन नाम और पोर्ट का उपयोग करें, आप के लिए रवाना आग जाएगा रिमोट मशीन - "आसानी से"।

जाओ dill, pathos, और ppft यहाँ: http://dev.pocoo.org/hg/sandbox/file/tip/pshell.py : https://github.com/uqfoundation

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