python - पायथन में गतिशील मॉड्यूल आयात




python-import (7)

2.7 / 3.1 से पुराने पायथन के साथ, यह बहुत कुछ है कि आप इसे कैसे करते हैं। नए संस्करणों के लिए, importlib.import_module और 3.1+ के लिए importlib.import_module देखें।

यदि आप भी चाहते हैं तो आप exec उपयोग कर सकते हैं।

ध्यान दें कि आप ऐसा करके मॉड्यूल की एक सूची आयात कर सकते हैं:

>>> moduleNames = ['sys', 'os', 're', 'unittest'] 
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)

पाइथन में सीधे डाइव से फिसल गया

मैं एक पायथन एप्लिकेशन लिख रहा हूं जो एक तर्क के रूप में एक आदेश के रूप में लेता है, उदाहरण के लिए:

$ python myapp.py command1

मैं चाहता हूं कि एप्लिकेशन एक्स्टेंसिबल हो, यानी, नए मॉड्यूल को जोड़ने में सक्षम होने के लिए जो मुख्य अनुप्रयोग स्रोत को बदलने के बिना नए आदेशों को लागू करता है। पेड़ कुछ ऐसा दिखता है:

myapp/
    __init__.py
    commands/
        __init__.py
        command1.py
        command2.py
    foo.py
    bar.py

तो मैं चाहता हूं कि एप्लिकेशन रनटाइम पर उपलब्ध कमांड मॉड्यूल ढूंढें और उपयुक्त एक निष्पादित करें।

वर्तमान में यह कुछ इस प्रकार लागू किया गया है:

command = sys.argv[1]
try:
    command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
    # Display error message

command_module.run()

यह ठीक काम करता है, मैं बस सोच रहा हूं कि क्या हम इस कोड के साथ क्या कर रहे हैं, इसे पूरा करने के लिए संभवतः एक और बेवकूफ तरीका है।

ध्यान दें कि मैं विशेष रूप से अंडे या विस्तार बिंदुओं का उपयोग नहीं करना चाहता हूं। यह एक ओपन-सोर्स प्रोजेक्ट नहीं है और मुझे उम्मीद है कि वहां "प्लगइन्स" न हों। बिंदु मुख्य अनुप्रयोग कोड को सरल बनाना है और प्रत्येक बार एक नया कमांड मॉड्यूल जोड़ा जाने पर इसे संशोधित करने की आवश्यकता को हटा देना है।


@monkut के समाधान के समान ही, लेकिन यहां वर्णित पुन: प्रयोज्य और त्रुटि सहनशीलता stamat.wordpress.com/dynamic-module-import-in-python :

import os
import imp

def importFromURI(uri, absl):
    mod = None
    if not absl:
        uri = os.path.normpath(os.path.join(os.path.dirname(__file__), uri))
    path, fname = os.path.split(uri)
    mname, ext = os.path.splitext(fname)

    if os.path.exists(os.path.join(path,mname)+'.pyc'):
        try:
            return imp.load_compiled(mname, uri)
        except:
            pass
    if os.path.exists(os.path.join(path,mname)+'.py'):
        try:
            return imp.load_source(mname, uri)
        except:
            pass

    return mod

ऐसा लगता है कि आप वास्तव में क्या चाहते हैं एक प्लगइन वास्तुकला है।

आपको setuptools पैकेज द्वारा प्रदान की गई प्रविष्टि बिंदु कार्यक्षमता पर एक नज़र रखना चाहिए। यह आपके एप्लिकेशन के लिए लोड किए गए प्लगइन खोजने का एक शानदार तरीका प्रदान करता है।


जैसा कि बताया गया है कि imp मॉड्यूल आपको कार्य लोड कर रहा है:

imp.load_source(name, path)
imp.load_compiled(name, path)

मैंने कुछ ऐसा करने के लिए पहले इनका उपयोग किया है।

मेरे मामले में मैंने परिभाषित विधियों के साथ एक विशिष्ट वर्ग को परिभाषित किया था। एक बार जब मैं मॉड्यूल लोड करता हूं तो मैं जांचता हूं कि कक्षा मॉड्यूल में थी या नहीं, और उसके बाद उस वर्ग का एक उदाहरण बनाएं, ऐसा कुछ:

import imp
import os

def load_from_file(filepath):
    class_inst = None
    expected_class = 'MyClass'

    mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1])

    if file_ext.lower() == '.py':
        py_mod = imp.load_source(mod_name, filepath)

    elif file_ext.lower() == '.pyc':
        py_mod = imp.load_compiled(mod_name, filepath)

    if hasattr(py_mod, expected_class):
        class_inst = getattr(py_mod, expected_class)()

    return class_inst

नीचे दिया गया टुकड़ा मेरे लिए काम किया:

>>>import imp; 
>>>fp, pathname, description = imp.find_module("/home/test_module"); 
>>>test_module = imp.load_module("test_module", fp, pathname, description);
>>>print test_module.print_hello();

अगर आप शेल-स्क्रिप्ट में आयात करना चाहते हैं:

python -c '<above entire code in one line>'

पायथन 2.7 के लिए अनुशंसित तरीका और बाद में importlib मॉड्यूल का उपयोग importlib है:

my_module = importlib.import_module('os.path')





python-import