About a plugin framework!

Peter Otten __peter__ at web.de
Tue Jun 8 11:57:06 CEST 2004


Simon Roses Femerling wrote:

> The way my app works is a python module (plugin) that contains (imbedded)
> XML defining the classname and some extra information and the app will be
> load the module using the classname:
> 
> Example:
> 
> ------ mymodule.py ----
> 
> __xml__ ="""
>     <data>
>         <classname>Test</classname>
>     </data>
> """

The xml stuff unnecessarily complicates things. Use a list with the names of
exposed classes 

__all__ = ["Test"]

If there is only one I'd rather follow a naming convention, i. e. the class
name "Test" would be mandatory.

 
> class Test:
>     def Msg(self):
>         print "Hello"
> 
> ---------------------------------
> 
> --- MyApp.py -----------
> 
> fp = open(f)
>  exec(fp) in globals()
> str = __xml__
> pxml = parsexml.ParseXML()
> pxml.BeginParse(str)
> cn = pxml.GetClassname()
> mymod = cn()   <-- Here is the error

Which of the following would you expect to succed?

>>> class Test: pass
...
>>> Test()
<__main__.Test instance at 0x40296acc>
>>> "Test"()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'str' object is not callable
>>> u"Test"()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'unicode' object is not callable

So the name is not enough - unicode or not. You have to get hold of the
class object, but that is no big deal:

>>> getattr(__main__, u"Test")()
<__main__.Test instance at 0x40296bcc>


> mymod.Msg()
> 
> ----------------------------------
> 
> The error is:
> 
> Traceback (most recent call last):
>   File "blackout.py", line 503, in onAttackMod
>     mymod = cn()
> TypeError: 'unicode' object is not callable
> 
> Any suggestions ? How can achieve this ?
> Each module (plugin) can have a different class name defined in the XML
> data.

Why?
 
> Besides this anyone have suggestions for a better plugin framework ? Maybe
> using imp module to dynamically import modules ?

If a plugin is in the python path, just do

plugin = __import__(pluginName)

and then retrieve the class

pluginClass = getattr(plugin, plugin.__all__[0])

Depending on whether you allow multiple plugins/classes at a time and how
you want to access them from your code you'd need registries (basically
python dictionaries) for plugin modules and clases.

Peter








More information about the Python-list mailing list