【问题标题】: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

【问题讨论】:

  • 全局状态不好的原因之一是它使单元测试变得困难。

标签: python import module python-module


【解决方案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()

根据docsreload()

重新加载之前导入的模块。

但是,如果您在测试用例中运行它,则在导入模块和重新加载模块之间不会有任何更改,对吧?为了进行更改,我认为您必须在测试用例运行时更改这些文件,这可能不是一个好主意。

【讨论】:

  • 我不会在运行期间更改字段,但我会在运行之间更改它们。由于测试用例已经完成了自己的导入,我需要有一种方法来更新更改,而不必退出解释器并重新开始。似乎即使我重新加载测试用例,它也会使用旧版本的模块代码,除非我在测试本身中包含重新加载语句。
  • 为测试用例启动一个新的解释器不是更容易吗? $ python testcase.py?这样你就可以确定你当前解释器中的任何东西都不会弄乱测试用例。
猜你喜欢
  • 2016-10-12
  • 2018-12-17
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 2013-08-12
  • 2019-03-14
  • 2012-12-10
相关资源
最近更新 更多