0

I have a directory with my_class.py

class MyClass:
    def __init__(self):
        self.a=1

    def message(self):
        print("message =",self.a)

I run the following code in a notebook:

from my_class import MyClass
MyClass().message() #outputs "message = 1"

Suppose now I edit my_class.py to replace self.a=1 with self.a=2. I would like to define a function

def my_reload(cls):
    # do something

such that running

my_reload(MyClass)
MyClass().message() #I want this to now output "message = 2"

would output 2 instead of 1. How do I do that?

For example, the following code still outputs 1:

import importlib
from inspect import getmodule
def my_reload(cls):
    module=getmodule(cls)
    importlib.reload(module)

And this

from inspect import getmodule
def my_reload(cls):
    module=getmodule(cls)
    __import__(module.__name__+"."+cls.__name__)

raises ModuleNotFoundError: No module named 'my_class.MyClass'; 'my_class' is not a package.

P.S. I would like to keep my import statement from my_class import MyClass as is.

UPD: This works, but feels slightly evil:

import importlib
from inspect import getmodule
def my_reload(cls):
    module=getmodule(cls)
    importlib.reload(module)
    eval("exec('from %s import %s')"%(module.__name__,cls.__name__))
    return eval(cls.__name__)

MyClass=my_reload(MyClass)
MyClass().message() #outputs "message = 2"

Is there a better solution?

  • It's not enough to reload the module; you need to rebind the name `MyClass` because it still refers to the original class. – chepner Jun 23 '23 at 17:52
  • 1
    Does this answer your question? [How to reload a module's function in Python?](https://stackoverflow.com/questions/7271082/how-to-reload-a-modules-function-in-python) – Woodford Jun 23 '23 at 18:08
  • @Woodford @chepner: those answers suggest that after I do `importlib.reload(module)`, I need to do `from my_class import MyClass` again. But how do I do that inside the `my_reload` function? In other words, what's the analog of `from my_class import MyClass` given only the `module` and `cls` variables? I tried `__import__(module.__name__+"."+cls.__name__)` and couldn't get it to work. – Pavel Galashin Jun 23 '23 at 18:16
  • The `from ... import ...` form is not implemented entirely in terms of a call to `import_module` (which should be used in place of a direct call to `__import__`). Once you have a reference to the new module (returned by `import_module`), you can do `MyClass = my_class.MyClass`. – chepner Jun 23 '23 at 19:40

0 Answers0