Plugins / Modularity

danmcleran at yahoo.com danmcleran at yahoo.com
Wed Oct 10 21:25:03 CEST 2007


On Oct 10, 12:43 pm, Robin Kåveland <kaavel... at gmail.com> wrote:
> On Oct 10, 8:38 pm, "danmcle... at yahoo.com" <danmcle... at yahoo.com>
> wrote:
>
>
>
> > On Oct 10, 12:30 pm, Robin Kåveland <kaavel... at gmail.com> wrote:
>
> > > Hi there. I'm basically in the process of writing my first substantial
> > > application in Python, and I've made a couple of (I'd like to say)
> > > design decisions so it won't just be a jumble. So, I've divided my
> > > program into three sub-packages, core, plugins and utilities.
>
> > > The core will be needed for the program to be run, but I've put it in
> > > a package by itself to make things more tidy.
> > > The utilities will be things that are handy to have (I'm thinking
> > > packages written by others that will make my work easier), but aren't
> > > necessary for the program to run. I'm not sure if this is needed yet,
> > > but I want to have the option in case it turns out to be useful.
>
> > > The plugins will basically be a package with modules adding
> > > functionality to the program, so to make it more extensible, and let
> > > others have a very simple way of extending the functionality without
> > > having to read a lot of source code and documentation. Adding a plugin
> > > should be really simple, preferrably you shouldn't have to modify any
> > > existing source, just put a .py file into the directory. This is where
> > > I'm sort of stuck. Does anyone know a way I can achieve this?
>
> > > This poses a couple of challenges for me, given the structure of my
> > > project and that I have no clue about how to do it. I'm thinking here
> > > that every plugin will have a main callable, which will recieve a
> > > Request object which can be queried for information, and an Action
> > > object which can be used to affect the state of the program to some
> > > degree. These will ideally be very simple (And for the moment, they
> > > obviously are).
>
> > > What I want, is a moment to 'contact' every module in the plugins
> > > package, and send these two objects to it's main callable. I also want
> > > to add a way for the program to load and reload plugin modules on the
> > > fly, so I can modify them without having to shut it down.
>
> > > Does anyone have some links for me? Alternatively any ideas?
>
> > > Thanks in advance.
>
> > I've just completed the initial launch basically this kind of software
> > framework. They way I did it was to parse xml files and load modules
> > and classes dynamically. After instantiating the classes, I call a
> > certain method that I expect to be present so that each class can
> > register any functionality it provides with a central registry within
> > the system. Overall, I've been very pleased with the way it turned
> > out. It's very easy to add functionality to the system, you simply add
> > an xml file along with some Python modules and you don't need to
> > change any existing code. I can provide some examples for you if you
> > like. Here's a little snippet from a Python script that loads modules
> > and classes:
>
> > def loadModule(moduleName):
> >     """
> >     Loads modules from within nested packages
> >     Reload ensures Python code is re-compiled.
> >     """
> >     mod        = __import__(moduleName)
> >     components = moduleName.split('.')
>
> >     for component in components[1:]:
> >         mod = getattr(mod, component)
> >         mod = reload(mod)
>
> >     return mod
>
> > def loadClass(moduleName, className):
> >     """
> >     Load a class from a module.
> >     Note: This does not create a class instance, it only loads the
> > code.
> >     """
> >     module = loadModule(moduleName = moduleName)
> >     c      = getattr(module, className)
>
> >     return c
>
> > You can try this out by passing in a string with with module and/or
> > class path and see that the module and/or class. Note that loadClass
> > does not create a class instance, so you'll have to instantiate it if
> > you want to, like this:
>
> > o = loadClass(modulePath,className)() #instantiates class that was
> > loaded dynamically
>
> Ah, fantastic! I didn't know about __import__, this is basically
> exactly what I need. I think I will manage, thanks a lot!

No problem, good luck.




More information about the Python-list mailing list