Intercepting module calls?

后端 未结 5 1182
粉色の甜心
粉色の甜心 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:20

    If you don't mind that import renderer results an object rather than a module, then see kindall's brilliant solution.

    If you want to make @property work (i.e. each time you fetch renderer.mytime, you want the function corresponding to OpenGLRenderer.mytime get called) and you want to keep renderer as a module, then it's impossible. Example:

    import time
    class OpenGLRenderer(object):
      @property
      def mytime(self):
        return time.time()
    

    If you don't care about properties, i.e. it's OK for you that mytime gets called only once (at module load time), and it will keep returning the same timestamp, then it's possible to do it by copying all symbols from the object to the module:

    # renderer.py
    specificRenderer = OpenGLRenderer()
    for name in dir(specificRenderer):
      globals()[name] = getattr(specificRenderer, name)
    

    However, this is a one-time copy. If you add methods or other attributes to specificRenderer later dynamically, or change some attributes later, then they won't be automatically copied to the renderer module. This can be fixed, however, by some ugly __setattr__ hacking.

提交回复
热议问题