如何重新加载Python子模块?

9

我正在使用Python (2.7.10)加载一个子模块,用的是from app import sub,其中sub有一个config变量。因此,我可以运行print sub.config并看到一堆配置变量。不是特别复杂。

如果我更改脚本中的配置变量,必须有一种方法重新加载模块并查看更改。我找到了一些指示表明reload(app.sub)可以工作,但我收到了一个错误:

NameError: name 'app' is not defined

如果我只是执行reload(sub),会出现以下错误:

TypeError: reload() argument must be module

如果我执行import app,我可以使用print app.sub.config查看配置并使用reload(app)重新加载。

-- 如果我执行import app然后运行

我找到了自动重新加载的说明: 在IPython中重新加载子模块

但是没有手动重新加载子模块的方法吗?


1
Python 的哪个版本? - Karen Clark
2
@KarenClark:必须使用Python2,因为在Python3中没有reload()函数。 - zondo
请提供需要翻译的具体内容。 - Amanda
4个回答

10

使用Python3,我尝试以下代码:

import importlib
import sys

def m_reload():
    for k,v in sys.modules.items():
        if k.startswith('your-package-name'):
            importlib.reload(v)

这在我的代码中引发了“RuntimeError: dictionary keys changed during iteration”。因此,我迭代字典项的副本,即for k,v in list(sys.modules.items()): - user1556435

0
当你使用 from foo import bar 时,你的命名空间中现在有一个名为 bar 的模块对象,因此你可以使用它。
from foo import bar

bar.do_the_thing()  # or whatever

reload(bar)

如果您想了解有关不同导入形式的更多详细信息,我个人发现this answer对我自己特别有帮助。


6
这种方法总是给我一个错误:"TypeError: reload()的参数必须是模块"。 - Amanda

0
from importlib import reload
import sys
ls=[]
#making copy to avoid regeneration of sys.modules
for i,j in sys.modules.items():
    r,v=i,j
    ls.append((r,v))

for i in ls:
    if i[0] == 'my_library_name':
        reload(i[1])

虽然这段代码可能解决了问题,但是如果您能附带说明解决问题的方法和原因,将有助于提高您的帖子质量,并可能获得更多点赞。请记住,您正在为未来的读者回答问题,而不仅仅是现在提问的人。请[编辑]您的答案,添加解释并指出适用哪些限制和假设。 - Adrian Mole

0
@6c1的答案对我没有起作用。
这是我修改后的答案,对我起了作用。
from foo import bar
bar.do_the_thing()

del bar
import sys
import importlib
importlib.reload(sys.modules['foo'])
from foo import bar

这在以下工作流程中非常有用:
  1. 打开Python终端
  2. 加载bar(即from foo import bar
  3. 意识到需要对bar进行更改
  4. bar进行更改
  5. 想要使用新的bar(即重新加载bar),而不关闭现有的Python终端

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接