Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python如何评估模块执行?_Python_Unit Testing - Fatal编程技术网

python如何评估模块执行?

python如何评估模块执行?,python,unit-testing,Python,Unit Testing,我在同一个目录中有两个文件,一个包含我的程序poker.py的内容,另一个包含测试用例poker\u test.py 在poker_test.py中,我执行以下命令来运行测试用例: import unittest import poker class PokerTest(unittest.TestCase): (...) 在我开发poker.py时,在poker.py的末尾,我有以下几点建议: if __name__ == "__main__": #imports Te

我在同一个目录中有两个文件,一个包含我的程序
poker.py
的内容,另一个包含测试用例
poker\u test.py

poker_test.py
中,我执行以下命令来运行测试用例:

import unittest
import poker


class PokerTest(unittest.TestCase):
      (...)
在我开发poker.py时,在
poker.py的末尾,我有以下几点建议:

if __name__ == "__main__":
    #imports Test case and unittest
    from poker_test import *
    unittest.main() 
一切都很好(目前),这种设置对于迭代开发非常有用。我的问题是,如果
poker\u test.py
依赖于
poker.py
,反之亦然,那么当我运行它时,python如何评估
poker.py

我有一个粗略的想法,但不知道“官方”的答案是什么

谢谢,
-M

避免像您在这里创建的循环依赖关系总是最合理的。然而,幸运的是,来自poker_测试导入的
位于
poker.py
的末尾,也就是说,在后者定义了它所定义的所有内容之后,因此它可以通过循环相关的
poker_测试.py
以良好的状态导入

然而,虽然这在当前Python版本中正常工作,但语言规范并不能保证这一点。为保证稳定性,请打破循环依赖关系,例如:

  • if\uuuu name\uuuu
    检查前的
    poker.py
    的所有“实质性”内容移动到例如
    \u poker.py
  • poker.py
    中,只需从\u poker import*
  • poker\u test.py
    中,使用
    import\u poker作为扑克,而不是
    import poker

  • 这样,依赖关系图就变成了非循环的,因此您的代码在任何正确的Python版本中都能按预期工作,包括假设的未来版本:-)。

    关于您是否应该这样做,正如Alex所说,不惜一切代价避免这样做。周期性进口是一种罪恶的状态

    撇开这一点不谈,看看发生了什么很有意思(大致上,模块导入机制是这样的。我的主要来源是导入系统上的Python 3.4.2文档)

    poker\u test.py中的行

    import poker
    
    执行时,系统首先检查模块是否已加载。加载的模块存在于一个名为
    sys.modules
    的字典中

    • 如果要导入的模块已经在
      sys.modules
      中,则
      poker\u test.py
      中对
      poker
      的任何引用都只指向该名称空间。(请注意,在周期性导入的情况下,模块可能已经添加到
      sys.modules
      ,但命名空间的填充可能尚未完全结束。该模块的执行可能会在显示
      导入此\u或\u其他\u模块
      的行暂停。)
    • 如果模块不在那里,则系统创建一个新名称空间,将其添加到
      sys.modules
      ,查找与
      poker
      模块相关联的代码(在本例中,位于
      poker.py
      )并开始执行,将所有变量放入新创建的名称空间中
    因此,您可能认为
    poker.py
    运行一次,而
    poker\u test.py
    运行一次,并且已经注意到
    poker
    是一个已加载的模块,因此导入到此结束。除了

    当模块作为原始脚本运行时,它将在
    sys.modules
    中注册为
    \uuuu main\uuuu
    ,而不是其实际名称

    因此,
    poker.py
    将被称为
    \uuuuu main\uuuuu
    模块,因此,当
    poker\u测试
    尝试运行
    import poker
    时,它无法在
    sys.modules
    下找到
    poker
    <代码>扑克
    将加载两次,一次作为
    \uuuu main\uuuu
    加载,另一次作为
    扑克
    加载。周期性导入是不受欢迎的,但是
    \uuuu main\uuu
    模块的周期性导入是完全不受欢迎的,因为创建两个相同(ish)名称空间的问题以及可能导致的潜在奇怪错误

    代码中还有两个复杂之处

    1) 来自扑克测试导入的
    *

    因为您正在执行一个
    import*
    ,而不是将从
    poker\u test
    创建的所有变量放在它自己的名称空间中,它会被抛出到
    \uuuu main\uuu
    名称空间中

    2)
    如果名称=主名称:

    由于您仅从
    poker\u test
    导入,如果模块是正在执行的主脚本,那么当
    poker
    poker\u test
    导入时,Python解释器将不会触及该行。因此,您的代码在概念上并不是真正的循环<代码>扑克
    作为
    \uuuuu main\uuuuuuu
    导入
    poker\u测试
    ,导入
    扑克
    并在那里停止。简单

    …所以我们不要做循环导入

    一些参考资料:


    请注意,unittest还支持有限的命令行参数:--在本例中,您要运行测试,而不是
    python poker.py
    ,您需要执行
    python-m unittest poker\u test.py
    ,Bob是您的叔叔。您甚至只能运行特定的测试
    python-m unittest poker\u test.PokerTest.testSomething