I know that the reload()
function can't affect the from <module> import <name>" which were used before the
reload()`, but I tested it and found something odd:
test1.py
:
message="before editing"
def printer():
print("reload",message)
test1.py
(changed):
message="after editing"
def printer():
print("reload",message)
then I used the interpreter and entered:
from test1 import printer
printer()
import test1
test1.printer()
#change the test1.py
reload(test1)
test1.printer()
printer()
after reload,the result is:
>>> test1.printer()
('reload:', 'after editing')
>>> printer()
('reload:', 'after editing')
So, why does printer()
see the change? I thought the reason may be variable binding.
Reloading updates the existing module. Functions from a module contain a reference to the module globals:
>>> printer.__globals__ is test1.__dict__
True
>>> 'message' in printer.__globals__
True
>>> printer.__globals__['message'] is test1.message
True
It is through this reference that globals like message
are resolved. Because reload()
function updates the existing module namespace, the printer
function object will use the new value.
The problem with reload()
and imported names from a module (rather than a reference to the module itself) is that those references are not updated. If you had changed the definition of the printer()
function itself rather than the message
global, then the imported reference to that function would not have changed.
Quoting from the reload()
function documentation:
When a module is reloaded, its dictionary (containing the module’s global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem.
Emphasis mine.