I have a python module with a lot of variables. These variables are used and changed by many other modules. And I want to reload this module from itself when it happens (for refresh).
How to do that?
upd: so.. this is me, question author, 8 years after the question publication date. I have zero idea why I would try to do something like that then.
If you read this, please attempt to use proper configuration management techniques (most of the time supplied by your framework) instead.
# ==================================
# foo.py
spam = 100
def set_spam(value):
spam = value
foo = reload(foo) # reload module from itself
# ==================================
# bar.py
import foo
print foo.spam # I expect 100
# assume that value changes here from some another modules (for example, from eggs.py, apple.py and fruit.py)
foo.set_spam(200)
print foo.spam # I expect 200
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.
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
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With