Intercepting module calls?

后端 未结 5 1142
粉色の甜心
粉色の甜心 2021-01-15 13:20

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.

5条回答
  •  粉色の甜心
    2021-01-15 13:30

    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.

提交回复
热议问题