首先,我知道它已经发布过,但是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
答案 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)
...