重新加载模块导致不同的结果
Posted
技术标签:
【中文标题】重新加载模块导致不同的结果【英文标题】:Reloading module causes different results 【发布时间】:2012-07-26 09:24:39 【问题描述】:在测试期间,我在测试用例中添加了一个重新加载命令,这样我就可以在几个不同的地方更改代码,而无需手动重新加载所有内容,我注意到重新加载似乎会影响测试结果。
这就是我所做的:
import mymodule
import mymodule.rules as rules
def testcase():
reload(mymodule)
reload(rules)
# The rest of the test case
一切都像这样正常工作,或者当两次重新加载都被注释掉时,但是当我注释掉第二次重新加载时,测试的结果是不同的。在重新加载过程中是否发生了一些我不知道的事情,一旦重新加载模块,就需要重新加载模块中的所有脚本?还有其他解释吗?
我不确定这是否相关,但 rules 是包含此行的包内的单独脚本:
from mymodule import Rule
【问题讨论】:
全局状态不好的原因之一是它使单元测试变得困难。 【参考方案1】:您问题中的信息相当模糊,您的术语也相当不标准。来自
rules 是 mymodule 中的一个单独脚本。
我推断mymodule
实际上是一个包,它似乎在导入时不会自动导入rules
。这意味着在执行后
import mymodule
不会有mymodule.rules
,但是执行后
import mymodule.rules as rules
模块rules
将被导入mymodule
的命名空间。 (旁注:后面的代码行通常写成from mymodule import rules
。)
在执行第一条reload()
语句后,您将获得mymodule
的frsh 副本,其中不包含mymodule.rules
- 这只会在第二条reload()
语句之后重新创建。
我不得不为这个答案做很多猜测,所以我可能弄错了。 reload()
语句有很多微妙之处,如其documentation 所示,因此最好仅在您非常熟悉 Python 的导入机制时使用它。
(另一个注意事项:如果rule.py
位于包mymodule
中,就像您的设置一样,您应该在那里使用相对导入。而不是
from mymodule import Rule
你应该这样做
from . import Rule
我还推荐from __future__ import absolute_import
以获得更透明的导入规则。)
【讨论】:
如果重新加载包意味着不包含规则模块,那么当代码尝试从规则中调用函数时,不应该引发异常吗? 另外,你是对的,我的意思是说包。我没有像往常一样使用“from mymodule import rules”的原因是,在这种导入之后 reload(rules) 不起作用。 规则只是一个类。 rules.py 是一堆函数,它们返回一些常用的 Rule 对象。不过,我会研究 absolute_import,谢谢。 @Skunkwaffle:最有可能的是,您最终得到了单个模块的两个实例,但我对您的设置知之甚少,无法确定。是的,如果有东西试图访问mymodule.rules
而它不存在,你会收到一条错误消息,但我怎么知道你没有呢?
我认为您可能对两个实例是正确的。我宁愿不在这里粘贴我所有的代码(其中有很多),但我会看看是否可以找到更多详细信息以进一步阐明结构。另外,我想解释说我从两种配置的测试用例中得到的结果暗示没有错误。如果不清楚,我深表歉意。【参考方案2】:
我不确定究竟是什么导致了您的问题,但我认为您可能误用了reload()
。
根据docs,reload()
会
重新加载之前导入的模块。
但是,如果您在测试用例中运行它,则在导入模块和重新加载模块之间不会有任何更改,对吧?为了进行更改,我认为您必须在测试用例运行时更改这些文件,这可能不是一个好主意。
【讨论】:
我不会在运行期间更改字段,但我会在运行之间更改它们。由于测试用例已经完成了自己的导入,我需要有一种方法来更新更改,而不必退出解释器并重新开始。似乎即使我重新加载测试用例,它也会使用旧版本的模块代码,除非我在测试本身中包含重新加载语句。 为测试用例启动一个新的解释器不是更容易吗?$ python testcase.py
?这样你就可以确定你当前解释器中的任何东西都不会弄乱测试用例。以上是关于重新加载模块导致不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
带参数的 routerLink 正在更改 URL 但不导航或重新加载组件