Prevent Python from caching the imported modules

后端 未结 8 1685
误落风尘
误落风尘 2020-11-28 07:40

While developing a largeish project (split in several files and folders) in Python with IPython, I run into the trouble of cached imported modules.

The problem is th

相关标签:
8条回答
  • 2020-11-28 07:44

    For Python version 3.4 and above

    import importlib 
    importlib.reload(<package_name>) 
    from <package_name> import <method_name>
    

    Refer below documentation for details.

    0 讨论(0)
  • There are some really good answers here already, but it is worth knowing about dreload, which is a function available in IPython which does as "deep reload". From the documentation:

    The IPython.lib.deepreload module allows you to recursively reload a module: changes made to any of its dependencies will be reloaded without having to exit. To start using it, do:

    http://ipython.org/ipython-doc/dev/interactive/reference.html#dreload

    It is available as a "global" in IPython notebook (at least my version, which is running v2.0).

    HTH

    0 讨论(0)
  • 2020-11-28 08:01

    Quitting and restarting the interpreter is the best solution. Any sort of live reloading or no-caching strategy will not work seamlessly because objects from no-longer-existing modules can exist and because modules sometimes store state and because even if your use case really does allow hot reloading it's too complicated to think about to be worth it.

    0 讨论(0)
  • 2020-11-28 08:01

    With IPython comes the autoreload extension that automatically repeats an import before each function call. It works at least in simple cases, but don't rely too much on it: in my experience, an interpreter restart is still required from time to time, especially when code changes occur only on indirectly imported code.

    Usage example from the linked page:

    In [1]: %load_ext autoreload
    
    In [2]: %autoreload 2
    
    In [3]: from foo import some_function
    
    In [4]: some_function()
    Out[4]: 42
    
    In [5]: # open foo.py in an editor and change some_function to return 43
    
    In [6]: some_function()
    Out[6]: 43
    
    0 讨论(0)
  • 2020-11-28 08:03

    Think twice for quitting and restarting in production

    The easy solution without quitting & restarting is by using the reload from imp

    import moduleA, moduleB
    from imp import reload
    reload (moduleB)
    
    0 讨论(0)
  • 2020-11-28 08:06

    You can use import hook machinery described in PEP 302 to load not modules themself but some kind of proxy object that will allow you to do anything you want with underlying module object — reload it, drop reference to it etc.

    Additional benefit is that your currently existing code will not require change and this additional module functionality can be torn off from a single point in code — where you actually add finder into sys.meta_path.

    Some thoughts on implementing: create finder that will agree to find any module, except of builtin (you have nothing to do with builtin modules), then create loader that will return proxy object subclassed from types.ModuleType instead of real module object. Note that loader object are not forced to create explicit references to loaded modules into sys.modules, but it's strongly encouraged, because, as you have already seen, it may fail unexpectably. Proxy object should catch and forward all __getattr__, __setattr__ and __delattr__ to underlying real module it's keeping reference to. You will probably don't need to define __getattribute__ because of you would not hide real module contents with your proxy methods. So, now you should communicate with proxy in some way — you can create some special method to drop underlying reference, then import module, extract reference from returned proxy, drop proxy and hold reference to reloaded module. Phew, looks scary, but should fix your problem without reloading Python each time.

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