Our example plugin module we'll call plugin.py and make as simple as possible:
I note that the second function appears to be referencing a variable metal that does not exist, and the third calls a function Transform that also seems to be missing in action. These are to be provided by the calling programme.
That module is named master.py and looks like this:
(To get this to work on your system you'll need to update the path in the second-last line.)
Run master.py and you should see five lines of output to the console.
I wrote this as a class to emphasise the difference between the setup work done in the init method and the execution work done in the call. The setup is likely done when our application launches, while the rendering of the code might occur many times during execution.
The importing uses the hook documented here. A namespace is just a dictionary mapping names to objects, instances, functions and so on. We can update this with whatever specific elements we require.
The example function here is trivial. In a more practical example _Transform() might (for example) provide important environment information to the plugin.
The nice thing about this architecture is that the plugin modules themselves need not be littered with all sorts of imports accessing internals of the application. Just remember to document the available functions for the plugin author.
Code similar to this provides the functionality of the new Wasp plugin system.
Maybe something like this will make it into the third edition of that invaluable reference, the Python Cookbook.
def Iron():
print 'Iron'
def Gold():
print metal
def Again():
Transform()
print 'Plastic'
I note that the second function appears to be referencing a variable metal that does not exist, and the third calls a function Transform that also seems to be missing in action. These are to be provided by the calling programme.
That module is named master.py and looks like this:
import os, sys
class Alchemy(object):
def __init__(self, filespec):
# add module to system path
filepath, filename = os.path.split(filespec)
if filepath not in sys.path:
sys.path.append(filepath)
# import module into a custom namespace
filename = os.path.splitext(filename)[0]
space = __import__(filename, globals(), locals(), [])
self.namespace = space.__dict__
def __call__(self, code):
# define a new function
def _Transform():
print ':: into ::'
# add that to our namespace along with a constant
self.namespace.update({'Transform': _Transform,
'metal': 'Gold'})
# ok, go for it!
exec code in self.namespace
myAlchemy = Alchemy('/path/to/plugin/plugin.py')
myAlchemy('Iron()\nTransform()\nGold()\nAgain()')
(To get this to work on your system you'll need to update the path in the second-last line.)
Run master.py and you should see five lines of output to the console.
I wrote this as a class to emphasise the difference between the setup work done in the init method and the execution work done in the call. The setup is likely done when our application launches, while the rendering of the code might occur many times during execution.
The importing uses the hook documented here. A namespace is just a dictionary mapping names to objects, instances, functions and so on. We can update this with whatever specific elements we require.
The example function here is trivial. In a more practical example _Transform() might (for example) provide important environment information to the plugin.
The nice thing about this architecture is that the plugin modules themselves need not be littered with all sorts of imports accessing internals of the application. Just remember to document the available functions for the plugin author.
Code similar to this provides the functionality of the new Wasp plugin system.
Maybe something like this will make it into the third edition of that invaluable reference, the Python Cookbook.
RELATED POSTS
No comments:
Post a Comment