【问题标题】:Importing a py file within itself在自身内部导入 py 文件
【发布时间】:2014-02-15 01:37:37
【问题描述】:

这是 test.py:

import sys

a = 50
b = [1,2]

def change():
    print "Here 1"
    import test
    print "Here 2"
    test.a = -1
    test.b = [0,1]
    return

def main():
    print "Here 3"
    change()
    print "Here 4"
    print a, b

if 1:
    main()

上面的python代码在系统上运行时会产生以下输出:

Here 3
Here 1
Here 3
Here 1
Here 2
Here 4
-1 [0, 1]
Here 2
Here 4
50 [1, 2]

我很困惑为什么没有“Here 1 \n Here 3”输出的无限循环。 print a, b 的输出如何证明是合理的?

【问题讨论】:

  • 感谢斯莱特的编辑!!
  • 如果您接受了一个您认为对您有帮助的答案并导致您的解决方案,那就太好了。如果遇到同样的问题,它还有助于快速引导读者找到有帮助的内容。

标签: python python-internals


【解决方案1】:

虽然user2367112's excellent answer 解释了为什么会发生这种情况,但这里的答案都没有提供解决方法。

有两种简单的方法可以实现所需的行为。

  1. 不要导入test,而是使用import __main__。如果您使用 import __main__ as test 分配别名,您甚至不必更改任何其他代码。
  2. 你可以设置sys.modules['test'] = sys.modules['__main__']告诉python“嘿,这个模块已经存在”。在此之后,import test 将不会重新导入模块,从而使您的代码按预期工作。 sys.modules 上的相关文档可以在 here 找到。

【讨论】:

    【解决方案2】:

    当您将文件作为脚本运行时,它不被视为test 模块。它被认为是__main__ 模块。

    当执行命中import test时,文件的第二次执行开始,模块被认为是test

    当再次执行import test 时,Python 会识别出它已经在导入test,并且不会重新执行该模块。相反,它只是将半初始化的test 模块对象加载到当前命名空间中并继续。 Python 的乐观假设是您已经编写了代码,以便在导入完成之前不需要test 的内容。

    当执行到分配给test.atest.b 时,这会影响test 模块,但不会影响__main__,尽管它们来自同一个文件。因此,导入模块中的print a, b 反映了新值,而__main__ 中的print a, b 反映了初始值。

    【讨论】:

    • 说得好。我的第一个想法是“他为什么要把__main__ 带进来,东西只导入一次并缓存在sys.modules 中”。我的第二个想法是……等一下,他对__main__ 位的看法是正确的(它完美地解释了总是很好的结果)。来自我的 +1。
    【解决方案3】:

    这个脚本的大致流程如下:

    1. Main 已运行,因此它会打印“Here 3”
    2. change 被调用,所以它打印 'Here 1'
    3. 导入test时python运行test的main函数
    4. 当第二次调用 change 时,python 足够聪明,知道 test 已经导入,因此它有效地跳过了该行。
    5. 导入的 main 运行结束
    6. 原始脚本运行完毕。

    【讨论】:

      【解决方案4】:

      一个文件只能导入一次。 'import test' 行在第一次遇到时成功。当第二次遇到它时,解释器将检查它是否已经被加载。

      当一个程序最初运行时,它不算被“导入”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多