How would I separate my Python File to multiple plugins?

前端 未结 1 1834
情深已故
情深已故 2020-12-10 22:24

So first thing I want to say: I have been looking into modules and such, I just don\'t quiet know how I would rewrite it to fit this in.

Project: What I have is a S

相关标签:
1条回答
  • 2020-12-10 23:09

    For a program of this size it's not really necessary to put your command functions into separate files, but I guess it is good organization. And good practice for when you write a program that has thousands of lines of code. :)

    One way to do this is to create a basic SkypeBot class without any command methods and then import the command methods from your plugins directory and add them to the class. It's easy enough to add new attributes to an existing class, and it doesn't matter if the new attributes are properties or methods, the syntax to add them is identical. (With a tiny bit more work it's even possible to add new attributes to an instance, so you can have multiple instances, each with their own individual set of commands. But I guess that's not necessary here, since a program that uses the SkypeBot class will normally only create a single instance).

    So we can break your question into two parts:

    1. How to add methods to an existing class.
    2. How to import those methods from other source files.

    As I said, 1) is easy. 2) is quite easy as well, but I've never done it before, so I had to do a little bit of research and testing, and I can't promise that what I've done is best practice, but it works. :)

    I don't know much about Skype, and I don't have that Skype4Py module, and as you said, the code above is not the complete program, so I've written some fairly simple code to illustrate the process of adding plugin methods from separate files to an existing class.

    The name of the main program is "plugin_demo.py". To keep things neat, it lives in its own directory, "plugintest/", which you should create somewhere in your Python path (eg where you normally keep your Python programs). This path must be specified in your PYTHONPATH environment variable.

    "plugintest/" has the following structure:

    plugintest/
        __init__.py
        plugin_demo.py
        plugins/
            __init__.py
            add.py
            multiply.py
    

    The __init__.py files are used by Python's import machinery to let it know that a directory contains a Python package, see 6.4. Packages in the Python docs for further details.

    Here are the contents of those files. Firstly, the files that go into "plugintest/" itself:

    __init__.py

    __all__ = ['plugin_demo', 'plugins']
    from plugintest import *
    

    plugin_demo.py

    #! /usr/bin/env python
    
    #A simple class that will get methods added later from plugins directory
    class Test(object):
        def __init__(self, data):
            self.data = data
    
    def add_plugins(cls):
        import plugins
    
        print "Adding plugin methods to %s class" % cls.__name__
        for name in plugins.__all__:
            print name
            plug = getattr(plugins, name)
            print plug
            method = getattr(plug, name)
            print method
            setattr(cls, name, method)
            print
        print "Done\n"
    
    add_plugins(Test)
    
    def main():
        #Now test it!
        t = Test([1, 2, 3]); print t.data
    
        t.multiply(10); print t.data
        t.add(5); print t.data
    
    if __name__ == '__main__':  
        main()
    

    And now the contents of the "plugintest/plugins/" directory:

    __init__.py

    __all__ = ['add', 'multiply']
    from plugintest.plugins import *
    

    add.py

    #A method for the Test class of plugin_demo.py
    def add(self, m):
        self.data = [m + i for i in self.data]
    

    multiply.py

    #A method for the Test class of plugin_demo.py
    def multiply(self, m):
        self.data = [m * i for i in self.data]
    

    If you cd to the directory containing the "plugintest/" folder, you should be able to run it with

    python plugintest/plugin_demo.py

    and if you cd to "plugintest/" itself

    python plugin_demo.py

    Also, in the interpreter (or another Python program), you should be able to do

    import plugintest

    and then run the main() function of "plugin_demo.py" with

    plugintest.plugin_demo.main()

    The other usual variations of from ... import ... etc should also work as expected.

    The function in "plugin_demo.py" that performs the magic of adding the imported methods to the Test class is add_plugins(). When it runs it prints out each method name, its module, and its function. This could be handy during development, but you'd probably comment out some of those print statements once the program's working properly.

    I hope this helps, and if you have any questions please don't hesitate to ask.

    0 讨论(0)
提交回复
热议问题