递归模块导入和重新加载

时间:2012-06-08 19:35:48

标签: python reload python-import

有人可以解释执行以下代码的原因:

文件“ hello.py ”:

import hello
print "hello"
hello = reload(hello)

执行python hello.py会打印以下内容吗?

hello
hello
hello
hello

为什么要4次?我知道当一个模块已经导入时,它不再被导入,但是重新加载力量来重新加载一个模块,即使它已经被加载了。我已经预料到了无限制的'你好'打印。

必须发生什么,reload不会重新加载模块?

2 个答案:

答案 0 :(得分:12)

python hello.py(A)运行代码一次,当(A)调用import hello代码再次运行时(B),当(A)和(B)调用reload(hello)时,代码再运行两次,共计四次。

通常,对于程序的生命周期,模块的代码将在以下时间执行:

  • 一旦是主要模块
  • 当任何模块(包括其自身)
  • 导入第一次时间时
  • 在模块上调用任何时间reload()

至于为什么reload()不是递归调用的,为了防止这种情况,PyImport_ReloadModule()函数(CPython,文件是import.c)有一个提前退出点:

http://svn.python.org/view/python/trunk/Python/import.c?view=markup#l2646

    ...
    existing_m = PyDict_GetItemString(modules_reloading, name);
    if (existing_m != NULL) {
        /* Due to a recursive reload, this module is already
           being reloaded. */
        Py_INCREF(existing_m);
        return existing_m;
    }
    ... load module code is below here

答案 1 :(得分:8)

reload保留当前正在重新加载的模块的列表(实际上是dict),以避免递归地重新加载模块。

请参阅http://hg.python.org/cpython/file/e6b8202443b6/Lib/imp.py#l236

这没有记录,但我认为你可能仍然可以依赖它。