如何在Python中批量重新加载模块?

4

我有两个自定义的包 pac1pac2。我以前会逐个导入所有模块,然后逐个重新加载它们进行更改,如下所示:

from pac1 import mod1
from pac1 import mod2
from pac1 import mod3
from pac2 import mod4
from pac2 import mod5

reload(mod1)
reload(mod2)
reload(mod3)
reload(mod4)
reload(mod5)

现在,我了解到可以批量导入模块并改进代码如下:
from pac1 import *
from pac2 import *

reload(mod1)
reload(mod2)
reload(mod3)
reload(mod4)
reload(mod5)

这样就是最好的方案吗?我的意思是,我能不能一次性重新加载所有包?
更新1:我经常修改这些模块。因此,在测试开始时导入它们后,我可能需要频繁地重新加载修改后的模块以反映更改。这是我重新加载模块的动力。
更新2:这个过程不一定是动态的。我只想通过将所有那些reload()融合成一个,使我的代码更简洁。

2
为什么在导入后需要立即重新加载它们? - DanielB
@DanielB 因为我经常修改它们。请查看已编辑的内容。 - user2881553
如果代码只是用于测试期间重新加载,那么它是否简洁真的很重要吗?如果您希望它更整洁,可以将其放在每个pac*文件中。 - DanielB
3个回答

1

sys.modules 中有一个全局模块列表(实际上是字典)。如果您想重新加载全局命名空间中的每个模块,请尝试以下操作:

import sys,imp
def reloader(globaldict):
    reloadkeys = set(globaldict)&set(sys.modules)
    for key in reloadkeys:
        if imp.is_builtin(key) == 0:
            reload(sys.modules[key])

reloader(locals())

或者,如果你想自己跟踪,请创建自己的模块列表mymodules,在导入每个模块后将其附加到列表中。然后您可以使用循环重新加载每个模块。


这是一种避免重新加载内置模块而不检查全局变量的方法:

import sys,imp
def reloader(globaldict):
    for key in sys.modules:
        if imp.is_builtin(key) == 0:
           reload(sys.modules[key])

此外,您可以在启动解释器后立即捕获sys.modules的状态,并使用类似的布尔运算将其排除在重新加载之外。

我认为简单地保留一个已导入模块的列表是最好的想法,从sys.modules重新加载所有模块可能会太麻烦了 - 例如,我有大约300个模块,想象一下每个模块都要重新加载几次... - Pawel Miech
请注意,我特别提供了代码,不会重新加载sys.modules中的每个模块。 - Marcin

0
你可以尝试类似这样的东西 this 或者,你可以看看 Werkzeug(Flask)是如何做的,它似乎使用 subprocess 来调用自身,或者至少是代码的主要部分。

仅提供链接的答案并不是好答案。如果链接失效,那么答案就变得无用了。请在这里包含答案的必要部分。 - ChrisF
@ChrisF 通常我也不赞成这样做...但在这种情况下,我认为如果Github出现问题,我们会有更大的麻烦;) - Wayne Werner
我认为对此的反驳是mitsuhiko完全可以删除他的分支……我确实尝试在我的回答中包含主要要点。 - Wayne Werner

-1

假设你真的需要重新加载它们,你现在的方式是最好的,因为它是显式的(而显式优于隐式)。这使得情况变得明朗(特别是因为这不是一种常规情况)

如果你真的需要动态地这样做,你可以尝试像这样:

import types

for k, v in globals().items():
    if not (k.startswith('__') and k.endswith('__')):
        if isinstance(v, types.ModuleType):
            reload(v)

有一个全局模块列表。 - Marcin
因为有一个全局模块列表。 - Marcin
@Marcin 我知道sys.modules,但他只想重新加载刚刚导入的模块。试图避免重新加载所有东西。 - DanielB
@Marcin,还避免了如果导入它自己的文件中出现无限循环的情况。 - DanielB

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