我在同一个目录中有两个文件,一个包含程序poker.py的内容,另一个包含测试用例poker_test.py。
在poker_test.py中,我执行以下命令来运行测试用例:
import unittest
import poker
class PokerTest(unittest.TestCase):
(...)然后,在poker.py的末尾,当我正在开发时,我有以下的逗号:
if __name__ == "__main__":
#imports Test case and unittest
from poker_test import *
unittest.main() 一切都很好(就目前而言),这个设置对于迭代开发来说是很棒的。我的问题是,在运行poker.py时,python如何评估它,因为poker_test.py依赖于poker.py,反之亦然?
我有一个粗略的想法,但我想知道“官方”的答案是什么。
谢谢,-M
发布于 2015-01-14 03:38:06
至于你是否应该这样做,正如亚历克斯所说的,不惜一切代价避免它。周期性进口是一种罪恶的状态。
撇开这一点不说,看看正在发生的事情是很有趣的(粗略地--它看起来模块导入机制是在Python中从一个版本调整到另一个版本的区域。我的主要源代码是导入系统上的Python3.4.2文档)
当poker_test.py中的行
import poker获取执行时,系统首先检查模块是否已加载。加载的模块位于一个名为sys.modules的字典中。
sys.modules中,那么任何对poker_test.py中的poker的引用都会指向该命名空间。(注意,在周期性导入的情况下,模块可能已经添加到sys.modules中了,但是命名空间的填充可能还没有完全结束。该模块的执行可能会暂停,在行上写着import this_or_that_other_module)sys.modules,查找与poker模块关联的代码(在本例中,位于poker.py中)并开始执行它,将所有变量放入新创建的命名空间中。因此,您可能认为poker.py只运行一次,而poker_test.py只运行一次,并且已经注意到poker是一个加载模块,因此导入就在那里结束。除了..。
当模块作为原始脚本运行时,它将在__main__中注册为sys.modules,而不是它的实际名称。
因此,poker.py将被称为__main__模块,因此,当poker_test尝试运行import poker时,它无法在sys.modules下找到poker。poker将被加载两次,一次是__main__,另一次是poker。周期性导入是不允许的,但是__main__模块的周期性导入被彻底谴责,因为创建两个相同(Ish)名称空间的问题以及可能导致的奇怪错误。
在您的代码中还有两个复杂的部分。
1) from poker_test import *
因为您正在执行一个import *,而不是将从poker_test创建的所有变量都放在自己的名称空间中,它将被抛到__main__命名空间中。
2) if __name__=='__main__':
因为只有当模块是正在执行的主要脚本时才从poker_test导入,所以当poker从poker_test导入时,Python解释器将不会触及这一行。所以你的代码并不是在概念上循环。poker作为__main__导入poker_test,导入poker并在那里停止。很简单!
...so,让我们不要做循环导入。
一些参考材料:
发布于 2015-01-14 00:06:42
避免循环依赖总是最可靠的,就像您在这里创建的那样。但是,您很幸运,因为from poker_test import *位于poker.py的末尾,即在后者定义了它所定义的所有内容之后,所以它可以通过循环依赖的poker_test.py以良好的状态导入。
但是,虽然这在当前的Python版本中是可行的,但语言规范并不保证这一点。为了稳定起见,打破循环依赖关系,例如:
poker.py检查前的所有“实质性”内容移到例如_poker.pypoker.py中,只需做from _poker import *poker_test.py中,而不是import poker中,使用import _poker as poker这样,您的依赖关系图就变成了循环图,因此您的代码将按照Python的任何正确版本(包括假设的未来版本:-)工作。
https://stackoverflow.com/questions/27932572
复制相似问题