开发者

Python; How to import methods to a class 'pluginstyle'?

I'm 开发者_StackOverflowtrying to make a class that imports its methods from plugin-like modules.

What I want for this class is for it to be able to import functions/vars from modules that are stored in a separate folder, i.e 'plugins'. Is this possible?

i know about __import__(), but how can i use it to import so they belong to this class?

lets say i have the following modules in the 'plugins' folder:

plugins/pluginA.py
plugins/pluginB.py

In these modules i have functions etc. And i want to be able to import and access them in the class. Maybe something like:

MyClass.pluginA.some_function_from_A()
MyClass.pluginB.some_function_from_B()

or perhaps like this

MyClass.some_function_fromA()
MyClass.some_function_fromB()


I would break the problem up into two parts: turning a list of files into a list of modules, then extending the class to include functions from those modules.

Brett Cannon has covered how to import a module from just a file path, so I won't duplicate that here… Although I'll suggest that you check out the glob module.

Second, how to extend a class to include the functions from a plugin. I would use something like this:

def extend(obj, plugin_modules):
    for module in plugin_modules:
        for export_name in dir(module):
            export = getattr(module, export_name)
            if callable(export):
                setattr(obj, export_name, export)


class MyClass(object):
    … code …

extend(MyClass, plugin_modules)

HOWEVER, I will warn you that it's unlikely that this is what you want, as the “plugin” functions on MyClass won't behave exactly like native methods… If you give more information about what you're trying to do, I might be able to give a more helpful answer.


I've been experimenting and rummaging around with google and i've come up with a solution that could work thanks to the tip about setattr and getatt from David Wolever and This page by Jesse Noller.

Here's what i have so far, and it appears to be working, needs cleanup and fine tuning though.

class MyClass(object):
    def __init__(self):
        pass

    def import_plugins(self):

        plugins_to_import = []
        attribs_to_exclude = ['__builtins__', '__doc__', '__file__', '__name__', '__package__']
        plugins = []
        plugins_dir = './plugins'

        # add the plugins directory to path
        if os.path.isdir(plugins_dir):
            sys.path.append(plugins_dir)
        else:
            print '%s is not a directory!' % (plugins_dir)

        # make a list of the plugins to import
        for plugin_file in os.listdir(os.path.abspath(plugins_dir)):
            #print plugin_file
            plugin_file_name, plugin_file_extension = os.path.splitext(plugin_file)
            if plugin_file_extension == '.py':
                plugins_to_import.append(plugin_file_name)

        # import the plugins to a list
        for plugin in plugins_to_import:
            plugins.append(__import__(plugin))

        # add the attributes to self
        for plugin in plugins:
            for attribute in dir(plugin):
                if attribute not in attribs_to_exclude:
                    self.__setattr__(attribute, getattr(plugin, attribute))

One problem now is to figure out how to pass self to the imports...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜