我有三个文件file_a.py
,file_b.py
和func.py
:
在func.py
中,我有:
import datetime
def a_simple_function():
print("hello from simple function")
return datetime.datetime.now()
global_variable = a_simple_function()
在file_b.py
中,我有:
from func import global_variable # second time import
def func_in_b():
print("print from file b:", global_variable)
在file_a.py
中,我有:
from func import global_variable # first time import
from file_b import func_in_b
print("print from file a:", global_variable)
func_in_b()
从file_a
运行时,我看到以下输出:
hello from simple function
print from file a: 2019-06-17 14:14:42.293202
print from file b: 2019-06-17 14:14:42.293202
为什么hello from simple function
出现一次而不是两次?我想我已经两次将其导入到不同的文件中。
基本上,我试图设置同时在global_variable
和file_a.py
中使用的file_b.py
,global_variable
由文件func.py
中的函数生成。 / p>
答案 0 :(得分:4)
这就是导入的工作方式,如记录的https://docs.python.org/3/tutorial/modules.html#more-on-modules所示。具体来说:
一个模块可以包含可执行语句以及函数定义。这些语句旨在初始化模块。只有在导入语句中遇到模块名称时,它们才会第一次执行。
基本上,import
语句首先检查sys.modules
是否已包含您的模块。如果是这样,则返回第二种情况下的现有引用。否则,将创建一个空模块对象,将其添加到sys.modules
中,然后仅通过运行.py文件进行填充。这样做的原因是为了避免循环导入引起的循环:即使对象仍然为空,也不会在这样的循环中重新加载模块。
在所有三个文件中对global_variable
的引用都指向完全相同的对象。您可以通过将以下代码添加到现有代码中来检入file_a
:
import func
import file_b
import sys
print(func.global_variable is file_b.global_variable is global_variable is sys.modules['func'].global_variable)
要记住的一个警告是,将模块作为脚本运行会将其放置在sys.modules
中,名称为__main__
。任何尝试以其常规名称导入的代码都会加载不同的模块对象,有时会导致意外的后果。
答案 1 :(得分:3)
Python在sys.modules
中缓存导入。因此,即使您多次导入同一模块,它也将使用缓存的版本,而不是重复导入。
详细了解module cache。
答案 2 :(得分:0)
这是因为当您将global_variable导入文件file_a.py
时,函数a_simple_function()
在内存中定义并保存在python缓存中。
下次将global_variable导入文件file_b.py
时,函数a_simple_function()
已在缓存中,因此将不再定义它,而是从那里获取global_variable
的值。 / p>