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

前端 未结 4 1869
温柔的废话
温柔的废话 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:49

    You might do something like this:

    for c in candidates:
        modname = os.path.splitext(c)[0]
        try:
            module=__import__(modname)   #<-- You can get the module this way
        except (ImportError,NotImplementedError):
            continue
        for cls in dir(module):          #<-- Loop over all objects in the module's namespace
            cls=getattr(module,cls)
            if (inspect.isclass(cls)                # Make sure it is a class 
                and inspect.getmodule(cls)==module  # Make sure it was defined in module, not just imported
                and issubclass(cls,base)):          # Make sure it is a subclass of base
                # print('found in {f}: {c}'.format(f=module.__name__,c=cls))
                classList.append(cls)
    

    To test the above, I had to modify your code a bit; below is the full script.

    import sys
    import inspect
    import os
    
    class PluginBase(object): pass
    
    def search(base):
        for root, dirs, files in os.walk('.'):
            candidates = [fname for fname in files if fname.endswith('.py') 
                          and not fname.startswith('__')]
            classList=[]
            if candidates:
                for c in candidates:
                    modname = os.path.splitext(c)[0]
                    try:
                        module=__import__(modname)
                    except (ImportError,NotImplementedError):
                        continue
                    for cls in dir(module):
                        cls=getattr(module,cls)
                        if (inspect.isclass(cls)
                            and inspect.getmodule(cls)==module
                            and issubclass(cls,base)):
                            # print('found in {f}: {c}'.format(f=module.__name__,c=cls))
                            classList.append(cls)
            print(classList)
    
    search(PluginBase)
    

提交回复
热议问题