How do I unload (reload) a Python module?

后端 未结 20 2348
轮回少年
轮回少年 2020-11-21 05:20

I have a long-running Python server and would like to be able to upgrade a service without restarting the server. What\'s the best way do do this?

if foo.py          


        
相关标签:
20条回答
  • 2020-11-21 05:35

    Removing modules from sys.modules requires 'None' types to be deleted as well.

    Method 1:

    import sys
    import json  ##  your module
    
    for mod in [ m for m in sys.modules if m.lstrip('_').startswith('json') or sys.modules[m] == None ]: del sys.modules[mod]
    
    print( json.dumps( [1] ) )  ##  test if functionality has been removed
    

    Method 2, using bookkeeping entries, to remove all dependencies:

    import sys
    
    before_import = [mod for mod in sys.modules]
    import json  ##  your module
    after_import = [mod for mod in sys.modules if mod not in before_import]
    
    for mod in [m for m in sys.modules if m in after_import or sys.modules[m] == None]: del sys.modules[mod]
    
    print( json.dumps( [2] ) )  ##  test if functionality has been removed
    

    Optional, just to be certain all entries are out, if you so choose:

    import gc
    gc.collect()
    
    0 讨论(0)
  • 2020-11-21 05:37

    Enthought Traits has a module that works fairly well for this. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

    It will reload any module that has been changed, and update other modules and instanced objects that are using it. It does not work most of the time with __very_private__ methods, and can choke on class inheritance, but it saves me crazy amounts of time from having to restart the host application when writing PyQt guis, or stuff that runs inside programs such as Maya or Nuke. It doesn't work maybe 20-30 % of the time, but it's still incredibly helpful.

    Enthought's package doesn't reload files the moment they change - you have to call it explicitely - but that shouldn't be all that hard to implement if you really need it

    0 讨论(0)
  • 2020-11-21 05:39

    For those like me who want to unload all modules (when running in the Python interpreter under Emacs):

       for mod in sys.modules.values():
          reload(mod)
    

    More information is in Reloading Python modules.

    0 讨论(0)
  • 2020-11-21 05:39

    Those who are using python 3 and reload from importlib.

    If you have problems like it seems that module doesn't reload... That is because it needs some time to recompile pyc (up to 60 sec).I writing this hint just that you know if you have experienced this kind of problem.

    0 讨论(0)
  • 2020-11-21 05:39

    Another way could be to import the module in a function. This way when the function completes the module gets garbage collected.

    0 讨论(0)
  • 2020-11-21 05:40

    I got a lot of trouble trying to reload something inside Sublime Text, but finally I could wrote this utility to reload modules on Sublime Text based on the code sublime_plugin.py uses to reload modules.

    This below accepts you to reload modules from paths with spaces on their names, then later after reloading you can just import as you usually do.

    def reload_module(full_module_name):
        """
            Assuming the folder `full_module_name` is a folder inside some
            folder on the python sys.path, for example, sys.path as `C:/`, and
            you are inside the folder `C:/Path With Spaces` on the file 
            `C:/Path With Spaces/main.py` and want to re-import some files on
            the folder `C:/Path With Spaces/tests`
    
            @param full_module_name   the relative full path to the module file
                                      you want to reload from a folder on the
                                      python `sys.path`
        """
        import imp
        import sys
        import importlib
    
        if full_module_name in sys.modules:
            module_object = sys.modules[full_module_name]
            module_object = imp.reload( module_object )
    
        else:
            importlib.import_module( full_module_name )
    
    def run_tests():
        print( "\n\n" )
        reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
        reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )
    
        from .tests import semantic_linefeed_unit_tests
        from .tests import semantic_linefeed_manual_tests
    
        semantic_linefeed_unit_tests.run_unit_tests()
        semantic_linefeed_manual_tests.run_manual_tests()
    
    if __name__ == "__main__":
        run_tests()
    

    If you run for the first time, this should load the module, but if later you can again the method/function run_tests() it will reload the tests files. With Sublime Text (Python 3.3.6) this happens a lot because its interpreter never closes (unless you restart Sublime Text, i.e., the Python3.3 interpreter).

    0 讨论(0)
提交回复
热议问题