好的,我写了一个小模块来解决这个困惑。我真诚地怀疑它是否没有错误。所以欢迎改进。
这个模块在 Py 2 和 3 上都能很好地工作。在 Python 2.7 和 Python 3.5 上试过。
# rld.py --> the reloading module
import sys
__all__ = ["reload"]
try:
# Python 2:
_reload = reload
from thread import get_ident
def reload (module):
if isinstance(module, basestring):
module = sys.modules[module]
if module.__name__==__name__:
raise RuntimeError("Reloading the reloading module is not supported!")
print ("Reloading: %s" % module.__name__)
# Get locals() of a frame that called us:
ls = sys._current_frames()[get_ident()].f_back.f_locals
# Find variables holding the module:
vars = [name for name, mod in ls.iteritems() if mod==module]
if len(vars)==0:
print ("Warning: Module '%s' has no references in this scope.\nReload will be attempted anyway." % module.__name__)
else:
print("Module is referenced as: %s" % repr(vars))
# Reload:
m = _reload(module)
for x in vars:
ls[x] = m
print("Reloaded!")
except NameError:
# Python 3:
from _thread import get_ident
def reload (module):
if isinstance(module, str):
module = sys.modules[module]
if module.__name__==__name__:
raise RuntimeError("Reloading the reloading module is not supported!")
print ("Reloading: %s" % module.__name__)
# Get locals() of a frame that called us:
ls = sys._current_frames()[get_ident()].f_back.f_locals
# Find variables holding the module:
vars = [name for name, mod in ls.items() if mod==module]
if len(vars)==0:
print ("Warning: Module '%s' has no references in this scope.\nReload will be attempted anyway." % module.__name__)
else:
print("Module is referenced as: %s" % repr(vars))
# Dereference all detected:
for x in vars:
del ls[x]
del sys.modules[module.__name__]
# Reimport:
m = __import__(module.__name__)
# Rebind to old variables:
for x in vars:
ls[x] = m
# Remap references in the old module
# to redirect all other modules that already imported that module:
for vname in dir(m):
setattr(module, vname, getattr(m, vname))
print("Reloaded!")
>>> # Usage:
>>> from rld import * # Always import it first - just in case
>>> import math
>>> math.cos
<built-in function cos>
>>> del math.cos
>>> math.cos
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'cos'
>>> reload(math)
Reloading: math
Module is referenced as: ['math']
Reloaded!
>>> math.cos
<built-in function cos>
>>> #-------------------------
>>> # This also works:
>>> import math as quiqui
>>> alias = quiqui
>>> del quiqui.cos
>>> quiqui.cos
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'cos'
>>> alias.cos
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'cos'
>>> reload("math")
Reloading: math
Module is referenced as: ['alias', 'quiqui']
>>> quiqui.cos
<built-in function cos>
>>> alias.cos
<built-in function cos>