单个文件 - 两个模块

时间:2016-12-02 15:38:43

标签: python python-import

每次我认为我理解Python导入的细节(最后!),新的东西让我回到了现实。请看一下这个简单的例子:

档案t1.py

import t2

x = "waiting for init"

def init():
    global x
    x = "OK"

if __name__ == '__main__':
    init()
    print("x =", x)
    t2.print_x()

注意不要使用错误的from t1 import x,这里是文件t2.py

import t1

def print_x():
    print("t1.x =", t1.x)

无论如何,输出不是我的预期:

$ python3 t1.py 

x = OK
t1.x = waiting for init

因此x in t1t1.x不同!

经过一番调查后,这个版本的t2.py对我有所帮助:

import t1

def print_x():
    import sys
    print(sys.modules['t1'].x)
    print(sys.modules['__main__'].x)

这两张照片的输出是:

waiting for init
OK

我发现它令人困惑。单个文件t1.py同时称为两个不同的模块:t1__main__。你能解释一下它的含义吗?在发布的代码中必须更改哪些内容才能获得t1.x = "OK"

1 个答案:

答案 0 :(得分:1)

TL; DR :是的,您有两个从 t1.py 源创建的内存模块。

这是因为Python的导入系统处理__main__模块的原因。基本上,它不会这样做。

__main__模块不是通过Python的标准导入机制导入的,而是与内置函数的初始化类似。

这就是为什么,当您在代码中从t1导入t1时,您实际上会再次导入

进行实验很容易。将t1.py模块的代码更改为:

import t2

x = "waiting for init"

if __name__ == "t1":
    print("t1.x = ", x)

if __name__ == '__main__':
    print("__main__.x =", x)

你会看到下一个打印在控制台中:

t1.x =  waiting for init
__main__.x = waiting for init

现在评论此模块中的第一行,您将得到:

__main__.x = waiting for init

因此,在第一种情况下,模块t1首先由解释器的启动机制初始化(其代码被执行)为__main__,然后t1由Python的导入系统从t2模块初始化(因此是再次执行。)

在第二种情况下,模块仅由解释器启动机制初始化。

PS。来自@ShadowRanger的好评如下:在脚本末尾打印sys.modules将显示如下内容:

<module '__main__' from 't1.py'>
<module 't1' from 'D:\\Projects\\python_test\\t1.py'>

演示模块是从同一个源创建的。