重新加载本地模块不起作用

时间:2018-06-25 00:18:46

标签: python python-3.x ipython python-importlib

首先,我知道它已经发布过,但是A)建议不起作用或B)建议是从名称空间中手动删除模块,然后像平常一样重新导入它。

我具有以下模块结构

basedir/
    pytools/
        __init__.py
        tools.py
    setup.py
    test.py

如果我在basedir中,则导入pytools并创建类testcls的对象。该类的实际属性可在tools.py中找到。 testcls有一个名为testfunc的方法,现在可以简单地打印出AAA

>>> import pytools
>>> test = pytools.testcls()
>>> test.testfunc()
AAA

假设我将testfunc()更改为现在打印BBB。我这样做,然后保存文件。然后,我重新加载模块,然后重试,它没有打印出BBB

>>> from importlib import reload
>>> reload(pytools)
>>> test = pytools.testcls()
>>> test.testfunc()
AAA

但是,如果我执行完全相同的过程,但是更改test.py,将该文件作为模块导入,在其中编辑函数,然后重新加载,则其行为与预期的一样:

>>> import test
>>> testvariable = test.testcls()
>>> testvariable.testfunc2()
AAA
# Change the function here
>>> from importlib import reload
>>> reload(test)
>>> testvariable = test.testcls()
>>> testvariable.testfunc2()
BBB

我真的不知道发生了什么,这真的让我很烦。同时,这也花费了我很多时间,但此刻我很生气。

有什么想法吗?

版本:

Python:3.6.5

解释器:IPython,6.2.1

1 个答案:

答案 0 :(得分:1)

让我们更笼统地命名:

basedir/
    testpackage/
        __init__.py
        testmodule.py
    test.py

如果testmodule.py包含:

class TestClass:
    def test_method(self):
        print("AAA")

然后,以下将按预期工作:

>>> from testpackage import testmodule
>>> obj = testmodule.TestClass()
>>> obj.test_method()
DDD
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testmodule)
>>> obj = testmodule.TestClass()
>>> obj.test_method()
EEE

但是,如果__init__.py具有以下内容:

from .testmodule import TestClass

然后您尝试导入(并重新加载) 软件包 而不是模块,则发生以下情况:

>>> import testpackage
>>> obj = testpackage.TestClass()
>>> obj.test_method()
EEE
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testpackage)
>>> obj = testpackage.TestClass()
>>> obj.test_method()
EEE

(不变)

请注意以下of the docs部分:

  

如果一个模块使用from…import…从另一个模块导入对象,则对另一个模块调用reload()不会重新定义从该模块导入的对象-一种解决方法是重新执行from语句,另一种方法是使用导入名称和限定名称(module.name)代替。

如果要按顺序重新加载模块和程序包,将再次按您的期望工作:

>>> import testpackage
>>> obj = testpackage.TestClass()
>>> obj.test_method()
HHH
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testpackage.testmodule)
>>> reload(testpackage)
>>> obj = testpackage.TestClass()
>>> obj.test_method()
III

但这似乎很愚蠢且容易出错,只需在第一个示例中使用该方法即可:

from testpackage import testmodule
...
reload(testmodule)
...