2

这是 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”输出的无限循环。如何证明打印 a、b 的输出是合理的?

4

4 回答 4

14

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

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

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

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

于 2014-01-24T06:55:14.450 回答
0

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

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

于 2014-01-24T06:54:59.537 回答
0

该脚本的一般流程如下:

  1. 主要运行,所以它打印'Here 3'
  2. change 被调用,所以它打印 'Here 1'
  3. 导入test时,python运行test的main函数
  4. 当第二次调用 change 时,python 足够聪明,知道 test 已经导入,因此它有效地跳过了该行。
  5. 导入的 main 完成运行
  6. 原始脚本完成运行。
于 2014-01-24T06:56:06.760 回答
0

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

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

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