Search code examples
pythonpython-importlib

Reload custom python function


I'm trying to reload from a python script a custom function because i'm editing the function constantly and i dont want to reload the kernel each time i make a change on the file. I have read that i can use importlib .

However, when i try to use reload i get ImportError: module Classifier not in sys.modules

My code:

from importlib import reload
from FilterFile import Classifier as foo

reload(foo)

I tried just using reload(Classifier) and reload(FilterFile import Classifier) , but i'm getting the same error.


Solution

  • In this case, Classifier isn't the module or a sub-module, it's something you've imported from the FilterFile module (from-imports actually still import everything from the module, but only allow you to access what you've requested).

    You need to do import FilterFile instead (you can still do something like import FilterFile as foo, as long as the thing you're reloading is a reference to the actual module).


    I tested the following as my Classifier function (the same logic applies for classes and such):

    def Classifier():
        print('before')
    

    While testing, I would change 'before' to 'after' during a delay. When I tried the following, no error occurred but Classifier didn't actually update unless called through the module:

    import time
    import FilterFile as bar
    from importlib import reload
    from FilterFile import Classifier as foo
    
    foo()             # "before"
    time.sleep(3.5)   # (a delay so I could change `Classifier`)
    reload(bar)
    foo()             # "before" <- wrong!!!
    bar.Classifier()  # "after"
    

    However, you can redo the from-import to update it:

    import time
    import FilterFile as bar
    from importlib import reload
    from FilterFile import Classifier as foo
    
    foo()             # "before"
    time.sleep(3.5)   # (a delay so I could change `Classifier`)
    reload(bar)
    from FilterFile import Classifier as foo
    foo()             # "after" <- hooray!!!
    

    I recommend wrapping importlib.reload() in your own function that also redoes your from-imports. There might be a hacky way to do this without needing a true import statement and without redoing the from-imports, but I hope this is acceptable for your purposes.