为什么函数似乎一次导入?

时间:2019-06-17 06:07:29

标签: python python-import

我有三个文件file_a.pyfile_b.pyfunc.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_variablefile_a.py中使用的file_b.pyglobal_variable由文件func.py中的函数生成。 / p>

3 个答案:

答案 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>