Dynamic importing of modules followed by instantiation of objects with a certain baseclass from said modules

前端 未结 4 1907
温柔的废话
温柔的废话 2021-01-04 20:31

I\'m writing an application. No fancy GUI:s or anything, just a plain old console application. This application, lets call it App, needs to be able to load plugins on startu

4条回答
  •  难免孤独
    2021-01-04 20:43

    Here is a meta-classier way to register the plugins:

    Define PluginBase to be of type PluginType. PluginType automatically registers any instance (class) in the plugins set.

    plugin.py:

    plugins=set()
    class PluginType(type):
        def __init__(cls, name, bases, attrs):
            super(PluginType, cls).__init__(name, bases, attrs)
            # print(cls, name,cls.__module__)
            plugins.add(cls)
    
    class PluginBase(object):
        __metaclass__=PluginType
        pass
    

    This is the part that the user writes. Notice that there is nothing special here.

    pluginDir/myplugin.py:

    import plugin
    class Foo(plugin.PluginBase):
        pass
    

    Here is what the search function might look like:

    test.py:

    import plugin
    import os
    import imp
    
    def search(plugindir):
        for root, dirs, files in os.walk(plugindir):
            for fname in files:
                modname = os.path.splitext(fname)[0]
                try:
                    module=imp.load_source(modname,os.path.join(root,fname))
                except Exception: continue
    
    search('pluginDir')
    print(plugin.plugins)
    

    Running test.py yields

    set([])
    

提交回复
热议问题