2010-07-15 12 views
6

मेरा पायथन एप्लिकेशन इस प्रकार बनाया गया है कि कुछ कार्यक्षमता प्लगइन के रूप में उपलब्ध है। वर्तमान में प्लगइन आर्किटेक्चर बहुत आसान है: मेरे पास एक प्लगइन्स फ़ोल्डर/पैकेज है जिसमें कुछ पायथन मॉड्यूल शामिल हैं। इस प्रकार मैं प्रासंगिक प्लगइन लोड:py2exe संकलन कोड में असम्पीडित पायथन प्लगइन की गतिशील लोडिंग

plugin_name = blablabla 
try: 
    module = __import__(plugin_name, fromlist='do_something') 
except ImportError: 
    #some error handling ... 

और उसके बाद निष्पादित करें:

try: 
    loans = module.do_something(id_t, pin_t) 
except xxx: 
    # error handling 

मैं एक Windows द्विआधारी py2exe का उपयोग करने के आवेदन संकलित करें। यह ठीक काम करता है, इसके अलावा यह तथ्य कि सभी प्लगइन्स बाइनरी में शामिल हैं (और होना चाहिए)। यह बहुत व्यावहारिक नहीं है, क्योंकि प्रत्येक नई प्लगइन के लिए, मुझे अपने आवेदन का एक नया संस्करण दोबारा बनाना और रिलीज़ करना होगा। यह बेहतर होगा अगर एक नई प्लगइन (यानी पायथन फ़ाइल) को कुछ एप्लिकेशन प्लगइन फ़ोल्डर में कॉपी किया जा सके, और फ़ाइल कोड में पायथन कोड को मेरे एप्लिकेशन द्वारा ऑन-द-फ्लाई का अर्थ दिया जा सकता है।

ऐसा करने का सबसे अच्छा तरीका क्या है?

(मेरे द्वारा चुने गए प्लगइन फ़ाइल की प्रत्येक पंक्ति को पढ़ने, और यह करने के लिए एक exec statement लागू करने। लेकिन वहाँ हो सकता है बेहतर तरीके ... के लिया है, हालांकि)

उत्तर

0

मैं तुम्हें pkg_resources entry_points विशेषताएं (setuptools से उपयोग करने का सुझाव/वितरण) प्लगइन खोज और तात्कालिकता को लागू करने के लिए: सबसे पहले, यह करने का एक मानक तरीका है; दूसरा, यह AFAIK का उल्लेख करने वाली समस्या का सामना नहीं करता है। आवेदन करने के लिए आपको बस इतना करना है कि कुछ प्लगइन को अंडे में पैकेज करना है जो कुछ प्रविष्टि बिंदु घोषित करता है (एक अंडे कई प्लगइन घोषित कर सकता है), और जब आप अपने अंडे को अपने अजगर वितरण में स्थापित करते हैं, तो यह सभी प्लगइन्स घोषित हो सकते हैं आपके आवेदन द्वारा खोजा गया। आप अपने आवेदन और "कारखाने" प्लगइन को एक ही अंडे में पैकेज भी कर सकते हैं, यह काफी सुविधाजनक है।

+1

उत्तर के लिए धन्यवाद। लेकिन क्या किसी को किसी को अपने कंप्यूटर पर पाइथन स्थापित करने की आवश्यकता नहीं होगी? (मैंने जो समाधान प्रस्तावित किया है, उसके लिए इसकी आवश्यकता होगी, अब मुझे लगता है कि) – Rabarberski

+0

आप सही हैं, यह आपके एप्लिकेशन और बाहरी प्लगइन दोनों के लिए एक ही पायथन स्थापना होना चाहिए। मैं मानता हूं कि यह काफी परेशान है। –

0

मुझे यकीन नहीं है कि आपको ज़िप लाइब्रेरी में प्लगइन फ़ाइलों को रखना होगा। ऐसा इसलिए हो सकता है क्योंकि आप अपनी स्क्रिप्ट को py2exe पैकेजिंग के लिए डिफ़ॉल्ट का उपयोग कर रहे हैं।

आप सका उपयोग करने का प्रयास संकुचित = झूठी (py2exe ListOfOptions में दस्तावेज के रूप में) जो py2exe द्वारा उत्पन्न library.zip को खत्म करेगा, और संभवतः आप अजगर मॉड्यूल का उपयोग करने की अनुमति देते हैं (यदि आपके प्लग इन से,, अजगर मॉड्यूल हैं मुझे लगता है आयात) एक "सामान्य" तरीके से, उन्हें अपने ज़िप या बाइनरी में पैकेज करने के लिए मजबूर होने के बजाय।

1

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

2

यदि आपको कोई फर्क नहीं पड़ता कि प्लगइन की .py फ़ाइलों के रूप में रिलीज़ हो जाएगी, तो आप निम्न की तरह कुछ कर सकते हैं। अपनी सभी प्लगइन को "प्लगइन" उपदिर के नीचे रखें, और एक खाली "__init__.py" बनाएं। रनटाइम करना, यह उस निर्देशिका में सभी मॉड्यूल के साथ पैकेज आयात करेगा। स्पष्टीकरण के लिए Dive In Python देखें ... लेकिन यहां अंततः मैं इसका उपयोग कर समाप्त करता हूं।

def load_plugin(path): 
    import imp 
    """Load plugin from directory and return list of modules""" 
    files = os.listdir(path) 
    test = re.compile(".py$", re.IGNORECASE)   
    files = filter(test.search, files)      
    filenameToModuleName = lambda f: os.path.splitext(f)[0] 
    moduleNames = sorted(map(filenameToModuleName, files)) 
    f, filename, desc = imp.find_module('plugin') 
    plugin = imp.load_module('plugin', f, filename, desc) 
    modules = [] 

    #print moduleNames 
    for m in moduleNames: 
     # skip any files starting with '__', such as __init__.py 
     if m.startswith('__'): 
      continue 
     try: 
      f, filename, desc = imp.find_module(m, plugin.__path__) 
      modules.append(imp.load_module(m, f, filename, desc)) 
     except ImportError: 
      continue 
    return modules 
+0

क्या उन मॉड्यूल के लिए संकलित संस्करण में मौजूद वर्गों को लोड करना संभव होगा? –

0

मैंने पाया pyinstaller के साथ बाहरी मॉड्यूल आयात करना कैसे करने के लिए (संकलित निष्पादन के शीर्ष पर, कार्यावधि में)। यह आंकड़े बताते हैं कि मूल रूप से, निष्पादन योग्य का मार्ग स्वचालित रूप से sys.path में जोड़ा गया था, लेकिन सुरक्षा कारणों से उन्होंने इसे किसी बिंदु पर हटा दिया। को यह पुन: सक्षम, का उपयोग करें:

sys.path.append(os.path.dirname(sys.executable)) 

इस फ़ाइलों को निष्पादन के रूप में ही रास्ते में बैठ .py आयात करने में सक्षम होगा। आप इस लाइन को रनटाइम हुक या मुख्य ऐप में जोड़ सकते हैं।

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