首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python如何评估模块执行?

python如何评估模块执行?
EN

Stack Overflow用户
提问于 2015-01-13 22:21:26
回答 2查看 491关注 0票数 4

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

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

代码语言:javascript
复制
import unittest
import poker


class PokerTest(unittest.TestCase):
      (...)

然后,在poker.py的末尾,当我正在开发时,我有以下的逗号:

代码语言:javascript
复制
if __name__ == "__main__":
    #imports Test case and unittest
    from poker_test import *
    unittest.main() 

一切都很好(就目前而言),这个设置对于迭代开发来说是很棒的。我的问题是,在运行poker.py时,python如何评估它,因为poker_test.py依赖于poker.py,反之亦然?

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

谢谢,-M

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-14 03:38:06

至于你是否应该这样做,正如亚历克斯所说的,不惜一切代价避免它。周期性进口是一种罪恶的状态。

撇开这一点不说,看看正在发生的事情是很有趣的(粗略地--它看起来模块导入机制是在Python中从一个版本调整到另一个版本的区域。我的主要源代码是导入系统上的Python3.4.2文档)

poker_test.py中的行

代码语言:javascript
复制
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下找到pokerpoker将被加载两次,一次是__main__,另一次是poker。周期性导入是不允许的,但是__main__模块的周期性导入被彻底谴责,因为创建两个相同(Ish)名称空间的问题以及可能导致的奇怪错误。

在您的代码中还有两个复杂的部分。

1) from poker_test import *

因为您正在执行一个import *,而不是将从poker_test创建的所有变量都放在自己的名称空间中,它将被抛到__main__命名空间中。

2) if __name__=='__main__':

因为只有当模块是正在执行的主要脚本时才从poker_test导入,所以当pokerpoker_test导入时,Python解释器将不会触及这一行。所以你的代码并不是在概念上循环。poker作为__main__导入poker_test,导入poker并在那里停止。很简单!

...so,让我们不要做循环导入。

一些参考材料:

正式Python 3.4.2导入系统上的文档

2008年comp.lang.python关于周期性进口的讨论

票数 4
EN

Stack Overflow用户

发布于 2015-01-14 00:06:42

避免循环依赖总是最可靠的,就像您在这里创建的那样。但是,您很幸运,因为from poker_test import *位于poker.py的末尾,即在后者定义了它所定义的所有内容之后,所以它可以通过循环依赖的poker_test.py以良好的状态导入。

但是,虽然这在当前的Python版本中是可行的,但语言规范并不保证这一点。为了稳定起见,打破循环依赖关系,例如:

  • poker.py检查前的所有“实质性”内容移到例如_poker.py
  • poker.py中,只需做from _poker import *
  • poker_test.py中,而不是import poker中,使用import _poker as poker

这样,您的依赖关系图就变成了循环图,因此您的代码将按照Python的任何正确版本(包括假设的未来版本:-)工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27932572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档