重新加载模块和依赖顶级模块

时间:2015-10-01 22:07:30

标签: python python-3.x python-internals

在python中,是否有一种机制:

  1. 重新加载顶级模块(sys.modules['__main__'])或
  2. 只是在运行时更新顶层模块中的函数吗?
  3. 假设我们有顶级dsu.py,我们想在运行时通过添加一个函数来修补导入的模块updating.simple,然后通过添加一个main()来修补dsu.py调用添加到updating.simple的函数。最后,我们要重新加载updating.simple以使用已修补的代码,然后重新加载dsu.py以使用信号处理程序中的reload-mechanism调用updating.simple中的新函数。

    dsu.py:

    import importlib, signal, time, sys
    import updating.simple
    
    def update_handler(sig, frame):
        importlib.reload(updating.simple)
        # 1. reload "this" module here or 2. reload only main()
    
    def main():
        while True:
            print("Result : %i" % updating.simple.computation(1,2))
            # patch with: print("Another: %i" % updating.simple.anothercomputation(2,1)) go here
            time.sleep(0.5)
    
    if __name__ == '__main__':
        signal.signal(signal.SIGUSR1, update_handler)
        main()
    

    updating\simple.py:

    def computation(a,b):
        return a * b
    

    虽然问题与动态更新(或猴子修补)有关,但我已添加了补丁和测试代码(python3 test.py)以供参考:

    https://bitbucket.org/vilvo/py-reload-module-and-dependent/src

    预期行为:

    $ python3 test.py 
    Starting the process: python3.4 ./dsu.py
    Result : 2
    Updating module with a patch that adds a method
    and the added method is called from the main()
    patching file updating/simple.py
    diff --git a/updating/simple.py b/updating/simple.py
    index 6bd6318..6434e5a 100644
    --- a/updating/simple.py
    +++ b/updating/simple.py
    @@ -1,2 +1,5 @@
     def computation(a,b):
         return a * b
    +
    +def anothercomputation(a,b):
    +    return a * b * b * a
    patching file ./dsu.py
    diff --git a/dsu.py b/dsu.py
    index 508f7c6..74d27e3 100644
    --- a/dsu.py
    +++ b/dsu.py
    @@ -8,6 +8,7 @@ def update_handler(sig, frame):
    
     def main():
         while True:
    +        print("Another: %i" % updating.simple.anothercomputation(2,1))
             print("Result : %i" % updating.simple.computation(1,2))
             time.sleep(0.5)
    
    diff --git a/updating/simple.py b/updating/simple.py
    index 6bd6318..6434e5a 100644
    --- a/updating/simple.py
    +++ b/updating/simple.py
    @@ -1,2 +1,5 @@
     def computation(a,b):
         return a * b
    +
    +def anothercomputation(a,b):
    +    return a * b * b * a
    Trigger dynamic software update with user signal
    Another: 4
    Result : 2
    Reverting patches
    Another: 4
    Result : 2
    Trigger dynamic software update with user signal
    Result : 2
    Stopping the process with pid 11547
    Cleaning files generated by Python
    Removing __pycache__/
    Removing updating/__pycache__/
    

    我的两个试验可以在git-repository中找到:

    $ git log --oneline
    7c7c828 Trial on reloading only updated main() and executing it
    2fd68d6 Study on dynamic update of a module and dependent with Python
    

    任何洞察力都表示赞赏,我也很好奇是否可以使用框架黑客。

0 个答案:

没有答案