2012-05-10 21 views
6

Nếu tôi xác định mô-đun mô-đun với một thư mục tương ứng module/, tôi có thể tự động tải các lớp học từ mô-đun trẻ em như a.py hoặc b.py?Làm thế nào để bạn tự động tải các lớp python từ một thư mục nhất định?

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

Điều này đòi hỏi phải biết tên lớp để tìm kiếm? Tôi có thể thiết lập một lớp cơ sở bằng cách nào đó sẽ tải những đứa trẻ này?

Trường hợp sử dụng cơ bản là cho phép người dùng viết một số mã của riêng mình mà chương trình sẽ tải. Tương tự như cách đường ray cho phép bạn viết bộ điều khiển, chế độ xem và mô hình của riêng bạn trong một số thư mục nhất định.

Mã để tải module động Tôi đã cho đến nay là

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 

Tôi đã hy vọng để sửa đổi nó để trở về đối tượng lớp.

+0

Nếu bạn kiểm tra khác [SE câu hỏi] (http://stackoverflow.com/questions/193161/what-is-the-best-project-cấu trúc-cho-một-python-ứng dụng) về cấu trúc dữ liệu mô-đun python, câu trả lời thứ ba đưa ra một câu trả lời ngắn khá tốt. Tôi đoán hơn bạn có thể làm một cái gì đó như: 'từ nhập khẩu mô-đun a' tự động. – Zenon

Trả lời

2

Bạn đang tìm kiếm pkgutil.walk_packages. Sử dụng này bạn có thể làm như sau:

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, nếu bạn không nhớ tham gia vào một sự phụ thuộc, bạn có thể thử các straight.plugin nạp, đó là phức tạp hơn một chút so với load chức năng đơn giản này.

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() 

Bên trong module thư mục, i ve hai mô-đun khác để thử nghiệm:

[♫ 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' 
Các vấn đề liên quan