简体   繁体   English

在自己内部导入py文件

[英]Importing a py file within itself

This is test.py: 这是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()

The above python code when ran on system generates the following output: 在系统上运行时上面的python代码生成以下输出:

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

What I am confused why is not there an infinite loop of "Here 1 \\n Here 3" outputs. 令我感到困惑的是为什么没有“Here 1 \\ n Here 3”输出的无限循环。 How can the print a, b outputs can be justified? 如何证明打印a,b输出是否合理?

When you run the file as a script, it is not considered to be the test module. 将文件作为脚本运行时,不会将其视为test模块。 It is considered to be the __main__ module. 它被认为是__main__模块。

When execution hits import test , a second execution of the file starts, where the module is considered to be test . 当执行命中import test ,文件的第二次执行开始,其中模块被认为是test

When execution hits import test again, Python recognizes that it's already importing test and does not reexecute the module. 当执行再次进入import test时,Python会识别出它已经导入test并且不会重新执行该模块。 Instead, it merely loads the half-initialized test module object into the current namespace and continues on. 相反,它只是将半初始化的test模块对象加载到当前命名空间中并继续。 Python's optimistic assumption is that you've written the code so that the contents of test won't be needed until the import finishes. Python的乐观假设是您编写了代码,以便在导入完成之前不需要test内容。

When execution hits the assignments to test.a and test.b , that affects the test module, but not __main__ , despite the fact that they came from the same file. 当执行命中test.atest.b ,它会影响test模块,但不影响__main__ ,尽管它们来自同一个文件。 Thus, the print a, b from the imported module reflects the new values, while the print a, b from __main__ reflects the initial values. 因此,来自导入模块的print a, b反映新值,而来自__main__print a, b反映初始值。

A file can only be imported once. 文件只能导入一次。 The 'import test' line succeeds the first time it is encountered. “导入测试”行在第一次遇到时成功。 When it is encountered a second time, the interpreter will check that it has already been loaded. 当第二次遇到它时,解释器将检查它是否已被加载。

When a program is initially run, it does not count as being 'imported'. 最初运行程序时,它不算作“导入”。

The general flow of this script is as follows: 该脚本的一般流程如下:

  1. Main is run, so it prints 'Here 3' 主要运行,所以打印'Here 3'
  2. change is called, so it prints 'Here 1' 更改被调用,因此它打印'Here 1'
  3. When importing test, python runs the main function of test 导入测试时,python运行test的主要功能
  4. When calling change the second time, python is smart enough to know that test is already imported, so it effectively skips that line. 当第二次调用更改时,python足够聪明,知道测试已经导入,因此它有效地跳过该行。
  5. The imported main finishes running 导入的主要完成运行
  6. The original script finishes running. 原始脚本完成运行。

While user2367112's excellent answer explains why this happens, none of the answers here offer a workaround. 虽然user2367112的优秀答案解释了为什么会发生这种情况,但这里的答案都没有提供解决方法。

There are two easy ways to achieve the desired behavior. 有两种简单的方法可以实现所需的行为。

  1. Rather than importing test , use import __main__ instead. 而不是导入test ,而是使用import __main__ If you assign an alias with import __main__ as test , you won't even have to change any other code. 如果您将带有import __main__ as test的别名指定import __main__ as test ,则甚至不必更改任何其他代码。
  2. You can set sys.modules['test'] = sys.modules['__main__'] to tell python "Hey, this module already exists". 你可以设置sys.modules['test'] = sys.modules['__main__']告诉python“嘿,这个模块已经存在”。 After this, import test will not re-import the module, thus making your code work as expected. 在此之后, import test将不会重新导入模块,从而使您的代码按预期工作。 The relevant docs on sys.modules can be found here . sys.modules上的相关文档可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM