2012-05-10 15 views
6

अगर मैं module/ के एक इसी निर्देशिका के साथ एक मॉड्यूल मॉड्यूल परिभाषित करते हैं, मैं गतिशील ऐसे a.py या b.py के रूप में बच्चों मॉड्यूल से कक्षाओं लोड कर सकते हैं?आप किसी दिए गए निर्देशिका से पाइथन कक्षाओं को गतिशील रूप से कैसे लोड करते हैं?

--module
----a.py
----b.py

इस के लिए खोज करने के लिए वर्ग के नाम जानने आवश्यकता होती है? क्या मैं एक बेस क्लास स्थापित कर सकता हूं जो किसी भी तरह इन बच्चों को लोड करेगा?

मूल उपयोग केस उपयोगकर्ता को अपने स्वयं के कुछ कोड लिखने की इजाजत देता है ताकि कार्यक्रम लोड हो जाए। जैसे ही रेल कुछ निर्देशिकाओं में आपके स्वयं के नियंत्रक, विचार और मॉडल लिखने की अनुमति देते हैं।

मॉड्यूल लोड करने के लिए कोड को गतिशील मैं अब तक

def load(folder): 
    files = {} 
    for filename in os.listdir(folder): 
     if (filename[0] != '_' and filename[0] != '.'): 
     files[filename.rstrip('.pyc')] = None 

    # Append each module to the return list of modules 
    modules = [] 
    mod = __import__(folder, fromlist=files.keys()) 
    for key in files.keys(): 
     modules.append(getattr(mod, key)) 

    return modules 

मैं कक्षा वस्तुओं वापस जाने के लिए इसे संशोधित करने की उम्मीद कर रहा था है।

+0

आप अन्य [एसई सवाल] को चेक करते हैं (http://stackoverflow.com/प्रश्न/1 9 3161/व्हाट-द-द-बेस्ट-प्रोजेक्ट-स्ट्रक्चर-फॉर-ए-पायथन-एप्लिकेशन) पाइथन मॉड्यूल डेटा स्ट्रक्चर के बारे में, तीसरा उत्तर एक बहुत अच्छा छोटा जवाब देता है। मुझे लगता है कि आप कुछ ऐसा कर सकते हैं: 'मॉड्यूल आयात से' गतिशील रूप से। – Zenon

उत्तर

2

आप pkgutil.walk_packages के लिए देख रहे हैं। का उपयोग करते हुए इस आप निम्न कर सकते हैं:

def load(root_import_path, is_valid=lambda entity: True): 
    """Returns modules in ``root_import_path`` that satisfy the ``is_valid`` test 

    :param root_import_path: An string name for importing (i.e. "myapp"). 
    :param is_valid: A callable that takes a variable and returns ``True`` 
        if it is of interest to us.""" 

    prefix = root_import_path + u"." 
    modules = [] 

    for _, name, is_pkg in walk_packages(root_import_path, prefix=prefix): 
     if is_pkg: 
      continue 
     module_code = __import__(name) 
     contents = dir(module_code) 
     for thing in contents: 
      if is_valid(thing): 
       modules.append(thing) 

    return modules 

Alternatly, यदि आप एक निर्भरता पर लेने से परहेज नहीं करते, तो आप straight.plugin लोडर है, जो एक छोटे से अधिक इस सरल load समारोह से जटिल है की कोशिश कर सकते।

0

निम्नलिखित दो मॉड्यूल, एक साथ काम कर रहे हैं, ऐसा कुछ करें। असल में, आप dir() अपने मॉड्यूल कर सकते हैं और कक्षाओं के वर्ग प्रकारों की जांच getattr से प्राप्त कर सकते हैं।

http://code.google.com/p/pycopia/source/browse/trunk/QA/pycopia/QA/shellinterface.py

http://code.google.com/p/pycopia/source/browse/trunk/aid/pycopia/module.py

2
#!/usr/bin/env python 

import os 
import sys 
import inspect 

def load_modules_from_path(path): 
    """ 
    Import all modules from the given directory 
    """ 
    # Check and fix the path 
    if path[-1:] != '/': 
     path += '/' 

    # Get a list of files in the directory, if the directory exists 
    if not os.path.exists(path): 
     raise OSError("Directory does not exist: %s" % path) 

    # Add path to the system path 
    sys.path.append(path) 
    # Load all the files in path 
    for f in os.listdir(path): 
     # Ignore anything that isn't a .py file 
     if len(f) > 3 and f[-3:] == '.py': 
      modname = f[:-3] 
      # Import the module 
      __import__(modname, globals(), locals(), ['*']) 

def load_class_from_name(fqcn): 
    # Break apart fqcn to get module and classname 
    paths = fqcn.split('.') 
    modulename = '.'.join(paths[:-1]) 
    classname = paths[-1] 
    # Import the module 
    __import__(modulename, globals(), locals(), ['*']) 
    # Get the class 
    cls = getattr(sys.modules[modulename], classname) 
    # Check cls 
    if not inspect.isclass(cls): 
     raise TypeError("%s is not a class" % fqcn) 
    # Return class 
    return cls 

def main(): 
    load_modules_from_path('modules') 
    # load the TestClass1 
    class_name = load_class_from_name('class1.TestClass1') 
    # instantiate the Testclass1 
    obj = class_name() 
    # using this object obj to call the attributes inside the class 
    print obj.testclass1() 

if __name__ == '__main__': main() 

अंदर मॉड्यूल निर्देशिका, मैं परीक्षण के लिए एक और दो मॉड्यूल किया है:

[♫ test] modules :~ pwd 
/tmp/dynamic_loader/modules 

[♫ test] modules :~ ls -lR 
total 32 
-rw-r--r-- 1 staff staff 138 Aug 30 21:10 class1.py 
-rw-r--r-- 1 staff staff 575 Aug 30 21:11 class1.pyc 
-rw-r--r-- 1 staff staff 139 Aug 30 21:11 class2.py 
-rw-r--r-- 1 staff staff 576 Aug 30 21:11 class2.pyc 

[♫ test] modules cat class1.py 

class TestClass1(object): 
    def testclass1(self): 
     print 'I am from testclass1' 

    def some_function(): 
     print 'some function 1' 
संबंधित मुद्दे

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