在Python中重新导入单个函数
在使用Python的交互模式时,你可以先导入一个模块。如果这个模块有了改动,比如修复了一个bug,你可以简单地使用reload()命令来重新加载这个模块。
但是,如果我不是导入整个模块,而是用'from M import f, g'这种方式导入的,那有没有办法只重新导入g呢?
我试过通过'del g'来删除这个函数,然后还把目录里的.pyc文件删掉,但都没用。当我再次用'from M import g'导入时,还是加载了旧的g。
4 个回答
2
因为这只是为了交互式解释器,我觉得像下面这样的做法:
def my_reload(mod, name):
reload(mod)
globals()[name] = getattr(mod, name)
myreload(somemodule, "some_function")
也不是太糟糕。这只是像平常一样重新加载模块,然后把指向旧对象的名字重新绑定到新对象上。这样做在所有可以用reload
的情况下都应该有效。或者,你可以编写代码来获取实际对象,并通过它的__name__
属性来获取名字。函数、类和模块都有__name__
属性,但像模块级别的字典就没有,所以灵活性就差一些。
这种做法不会替换其他地方对对象的引用,除了全局的引用,但即使你最开始是用点号命名访问的,reload
也不会替换那些引用。一旦对一个对象的引用变得松散,你就没什么办法了。
5
对于 from M import f, g
这种写法,如果 M
不是一个官方的 Python 模块,可以使用:
import sys
import importlib
importlib.reload(sys.modules['M'])
然后,重新导入 f
和 g
,可以使用:
from M import f,g
如果 M
是一个官方的 Python 模块,那就使用:
import importlib
importlib.reload(M)
from M import f,g
9
当你使用 from foo import bar
这行代码时,其实是把整个模块都引入了。你只是把符号 bar
的一个副本放到了当前的命名空间里。换句话说,你并不是单独引入这个函数。
另外,reload
这个功能并不是完全可靠的(比如它对编译过的C模块就不管用)。我建议你退出并重新启动你的解释器。