I\'m trying to \'intercept\' all calls to a specific module, and reroute them to another object. I\'d like to do this so that I can have a fairly simple plugin architecture.
My answer is very similar to @kindall's although I got the idea elsewhere. It goes a step further in the sense that it replaces the module object that's usually put in the sys.modules
list with an instance of a class of your own design. At a minimum such a class would need to look something like this:
File renderer.py
:
class _renderer(object):
def __init__(self, specificRenderer):
self.specificRenderer = specificRenderer
def __getattr__(self, name):
return getattr(self.specificRenderer, name)
if __name__ != '__main__':
import sys
# from some_module import OpenGLRenderer
sys.modules[__name__] = _renderer(OpenGLRenderer())
The __getattr__()
method simply forwards most attribute accesses on to the real renderer object. The advantage to this level of indirection is that with it you can add your own attributes to the private _renderer
class and access them through the renderer
object imported just as though they were part of an OpenGLRenderer
object. If you give them the same name as something already in an OpenGLRenderer
object, they will be called instead, are free to forward, log, ignore, and/or modify the call before passing it along -- which can sometimes be very handy.
Class instances placed in sys.modules
are effectively singletons, so if the module is imported in other scripts in the application, they will all share the single instance created by the first one.