如何在Python中创建扩展加载器?

时间:2012-01-23 22:47:48

标签: python module

我希望通过在运行时根据模块可能具有的某些属性枚举和加载某些指定文件夹中的模块来改进我编写的Python框架。

可能属性如:仅在某些元数据字段中包含特定值(如标记)的模块,或者可能只包含从某个基类派生的类的模块。

例如,让我们说扩展是支持不同类型身份验证的插件 - 我希望我的框架能够在运行时发现可能的插件而无需显式配置

这似乎是这种"扩展加载"应该是可能的,而且之前可能已经完成了数十万次,没有一个曾经想过的搜索查询正在改变任何事情,而且我不知道一个已经通过阅读某人开始实现这一目标的一个好的特定项目别的方法。

任何有关构建此类事物的方法的指针(甚至是更多Pythonic方式来考虑这个问题的建议)都会很棒。

1 个答案:

答案 0 :(得分:2)

(A 良好的答案会给出概述和选项,所以不要急于接受我的快速回答。)

我在我的一个项目中执行此操作,以便在不使用import *和硬编码名称的情况下将所有模块加载到包中。该代码可在Google Code上下文中查看。

SPECIES = []
'''An automatically generated list of the available species types.'''

def _do_import():
    '''Automatically populates SPECIES with all the modules in this
    folder.

    :Note:
        Written as a function to prevent local variables from being
        imported.
    '''
    import os

    for _, _, files in os.walk(__path__[0]):
        for filename in (file for file in files if file[0] != '_' and file[-3:] == '.py'):
            modname = filename[:filename.find('.')]
            mod = __import__(modname, globals(), fromlist=[])
            for cls in (getattr(mod, s) for s in dir(mod)):
                if cls is not Species and type(cls) is type and issubclass(cls, Species):
                    if getattr(cls, '_include_automatically', True):
                        SPECIES.append(cls)
                        globals()[cls.__name__] = cls

_do_import()