How to reload python module from itself?

There are a number of problems with what you're trying to achieve, unless you're deliberately setting up a self-modifying code system, which it doesn't look like you are.

1. Global variables

spam = 100

def set_spam(value):
    spam = value
    foo = reload(foo) #reload module from itself

This is not going to work. Because of how Python closures work, your spam = value line is going to create a new local variable spam within your set_spam function, which then won't get used. To properly change the value of the global spam, you have to use the global keyword, as such:

spam = 100

def set_spam(value):
    global spam
    spam = value

2. Reloading modules "from themselves"

As far as I know, there's no way to actually do this, nor should you need to. Any module you've import-ed is called from some other module, all the way up to __main__. You would simply refresh it from that calling module. Yes, you could attempt to self-import a module (though there might be infinite loop issues, as mentioned by mgilson), but even then (using an example named "foo"), if you had it import itself, you'd just have foo.foo, and doing something like foo.reload(foo) (if that's even valid) would simply reload the sub-foo, not the base one.

3. Reloading foo.py at all

# ==================================
# foo.py

spam = 100

def set_spam(value):
    global spam
    spam = value

Note how at the top of this code, you're assigning 100 to spam. Every time you import the module, you'll be doing that again. So, even if you've already changed the value of spam in the code that's imported foo, when you reload the module, you'll actually be destroying the change you just made. Example:

>>> import foo
>>> foo.spam
100
>>> foo.spam = 9
>>> foo.spam
9
>>> reload(foo)
>>> foo.spam
100

So if you want to keep the changes you've made to the variable in foo, you should not reload the module. Furthermore, you really don't even need to use a set_spam function to change spam, you can just set it directly, as I did.

4. Trying to use this "changed" module value in other modules

Finally, if I understand correctly what you're trying to do, that's not going to work. This is in large part because of something I mentioned in part 3, wherein every time you load foo, the spam=100 line is going to reset the value of spam. In the same way, if you import the foo module in two different other modules, when each one imports it, they're each going to start out with spam = 100, completely independently of what the other module does with foo.spam. Example, if both bar1.py and bar2.py contain the line import foo:

>>> import bar1, bar2
>>> bar1.foo.spam
100
>>> bar2.foo.spam
100
>>> bar1.foo.spam = 200
>>> bar1.foo.spam
200
>>> bar2.foo.spam
100

With more explanation about what you're trying to do, we could help you restructure your code to make it work better.


Here

import sys

reload(sys.modules[__name__])

NB, this does not work with the main module but with any other module.


In Python 2.6.2 it is simple. Assume your module is named "t" and is defined as follows:

import imp

def reload():
    name="t"
    imp.load_module(name,*imp.find_module(name))

print("loaded")

After you have loaded this module add another member it and execute t.reload().

p.s. I guess everybody thinks this is a bad idea: they're probably right, but if you're interactively developing a module maybe it makes things more convenient. Just take it out before you distribute your code to others or they might get confused.

Tags:

Python