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.