首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >'reload‘的递归版本

'reload‘的递归版本
EN

Stack Overflow用户
提问于 2013-03-20 01:57:23
回答 10查看 9.4K关注 0票数 33

当我开发Python代码时,我通常以一种特别的方式在解释器中测试它。我将对其进行import some_module、测试、查找错误、修复错误并保存,然后使用内置的reload函数执行reload(some_module)并再次测试。

然而,假设我在some_module中有import some_other_module,并且在测试some_module时,我在some_other_module中发现了一个错误并修复了它。现在调用reload(some_module)不会递归地重新导入some_other_module。我必须手动重新导入依赖项(通过执行reload(some_module.some_other_module)import some_other_module; reload(some_other_module)之类的操作),或者,如果我更改了一大堆依赖项,并且忘记了需要重新加载的内容,则需要重新启动整个解释器。

更方便的是,如果有一些recursive_reload函数,我可以只执行recursive_reload(some_module),让Python不仅重新加载some_module,而且递归地重新加载some_module导入的每个模块(以及每个模块导入的每个模块,等等),这样我就可以确定我没有使用some_module所依赖的任何其他模块的旧版本。

我不认为Python中有任何内置的东西可以像我在这里描述的recursive_reload函数那样工作,但是有没有一种简单的方法可以把这些东西组合在一起呢?

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2013-06-19 23:08:46

我也遇到过同样的问题,你启发了我去解决这个问题。

代码语言:javascript
复制
from types import ModuleType

try:
    from importlib import reload  # Python 3.4+
except ImportError:
    # Needed for Python 3.0-3.3; harmless in Python 2.7 where imp.reload is just an
    # alias for the builtin reload.
    from imp import reload

def rreload(module):
    """Recursively reload modules."""
    reload(module)
    for attribute_name in dir(module):
        attribute = getattr(module, attribute_name)
        if type(attribute) is ModuleType:
            rreload(attribute)

或者,如果您正在使用IPython,只需在启动时使用dreload或传递--deep-reload即可。

票数 34
EN

Stack Overflow用户

发布于 2013-03-20 01:58:31

如果实际编写一些测试用例,并在每次修改完模块后运行它们,不是更简单吗?

你所做的是很酷的(你本质上是在使用TDD (测试驱动开发),但是你做错了。

考虑到使用编写的单元测试(使用默认的python unittest模块,或者更好的是nose),你会得到可重用的稳定的的测试,并帮助你检测代码中的不一致,比在交互环境中测试你的模块更快,更好。

票数 4
EN

Stack Overflow用户

发布于 2015-02-06 12:02:43

我也遇到过同样的问题,我建立了@Mattew和@osa的答案。

代码语言:javascript
复制
from types import ModuleType
import os, sys
def rreload(module, paths=None, mdict=None):
    """Recursively reload modules."""
    if paths is None:
        paths = ['']
    if mdict is None:
        mdict = {}
    if module not in mdict:
        # modules reloaded from this module
        mdict[module] = [] 
    reload(module)
    for attribute_name in dir(module):
        attribute = getattr(module, attribute_name)
        if type(attribute) is ModuleType:
            if attribute not in mdict[module]:
                if attribute.__name__ not in sys.builtin_module_names:
                    if os.path.dirname(attribute.__file__) in paths:
                        mdict[module].append(attribute)
                        rreload(attribute, paths, mdict)
    reload(module)
    #return mdict

有三点不同:

  1. 在一般情况下,reload(模块)也必须在函数的末尾调用,正如@osa所指出的那样。带有循环导入依赖项的

模块之前发布的代码将永远循环,所以我添加了一个列表字典来跟踪由其他模块加载的模块集。虽然循环依赖并不酷,但Python允许循环依赖,所以这个重载函数也会处理它们。

  1. 我添加了一个允许重载的路径列表(默认是'')。有些模块不喜欢以正常的方式重新加载(如here).

所示

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15506971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档