gpt4 book ai didi

python - python如何评估模块执行?

转载 作者:太空狗 更新时间:2023-10-30 02:30:17 27 4
gpt4 key购买 nike

我在同一目录中有两个文件,一个包含我的程序 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()

一切正常(目前)并且此设置非常适合迭代开发。我的问题是 python 在我运行它时如何评估 poker.py,因为 poker_test.py 依赖于 poker.py,反之亦然?

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

谢谢,-M

最佳答案

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

除此之外,看看发生了什么很有趣(粗略地 - 看起来模块导入机制是 an area that gets tweaked from version to version in Python 。我的主要来源是导入系统上的 Python 3.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 是一个加载模块,所以导入到此结束。除了...

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

因此 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 导入,所以当从 导入 poker 时,Python 解释器不会触及该行>扑克测试。所以你的代码在概念上并不是真正的循环。 poker 作为 __main__ 导入 poker_test 导入 poker 并停在那里。很简单!

...所以我们不要进行循环导入。

一些引用资料:

Official Python 3.4.2 docs on the import system

2008 comp.lang.python discussion on cyclical imports

关于python - python如何评估模块执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27932572/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com