How to dynamically reload function in Python?

361 Views Asked by At

I'm trying to create a process that dynamically watches jupyter notebooks, compiles them on modification and imports them into my current file, however I can't seem to execute the updated code. It only executes the first version that was loaded.

There's a file called producer.py that calls this function repeatedly:

import fs.fs_util as fs_util

while(True):
    fs_util.update_feature_list()

In fs_util.py I do the following:

from fs.feature import Feature
import inspect
from importlib import reload
import os 


def is_subclass_of_feature(o):
    return inspect.isclass(o) and issubclass(o, Feature) and o is not Feature

def get_instances_of_features(name):
    module = __import__(COMPILED_MODULE, fromlist=[name])
    module = reload(module)
    feature_members = getattr(module, name)
    all_features = inspect.getmembers(feature_members, predicate=is_subclass_of_feature)
    return [f[1]() for f in all_features]

This function is called by:

def update_feature_list(name):
    os.system("jupyter nbconvert --to script {}{} --output {}{}"
            .format(PATH + "/" + s3.OUTPUT_PATH, name + JUPYTER_EXTENSION, PATH + "/" + COMPILED_PATH, name))
    features = get_instances_of_features(name)
    for f in features:
        try:
            feature = f.create_feature()
        except Exception as e:
            print(e)

There is other irrelevant code that checks for whether a file has been modified etc.

I can tell the file is being reloaded correctly because when I use inspect.getsource(f.create_feature) on the class it displays the updated source code, however during execution it returns older values. I've verified this by changing print statements as well as comparing the return values.

Also for some more context the file I'm trying to import:

from fs.feature import Feature


class SubFeature(Feature):

    def __init__(self):
        Feature.__init__(self)

    def create_feature(self):
        return "hello"

I was wondering what I was doing incorrectly?

1

There are 1 best solutions below

0
aphsai On BEST ANSWER

So I found out what I was doing wrong.

When called reload I was reloading the module I had newly imported, which was fairly idiotic I suppose. The correct solution (in my case) was to reload the module from sys.modules, so it would be something like reload(sys.modules[COMPILED_MODULE + "." + name])