Why the function seems to import once?

I have three files file_a.py, file_b.py and func.py:

In func.py, I have:

import datetime

def a_simple_function():
    print("hello from simple function")
    return datetime.datetime.now()

global_variable = a_simple_function()

In file_b.py, I have:

from func import global_variable  # second time import

def func_in_b():
    print("print from file b:", global_variable)

In file_a.py, I have:

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()

When run from file_a, I see the following output:

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

Why does hello from simple function appear once instead of twice? I think I've imported it twice in different files.

Basically I am trying to set a global_variable used both in file_a.py and file_b.py, the global_variable is generated by a function in file func.py.

Upvotes: 2

Views: 98

Answers (3)

Shadowfax
Shadowfax

Reputation: 586

This is because when you imported global_variable in file file_a.py, the function a_simple_function() is defined in memory and saved in python cache. The next time you import the global_variable in file file_b.py, the function a_simple_function() is already in cache so it will not be defined again, instead you will take the value of global_variable from there.

Upvotes: 0

Mad Physicist
Mad Physicist

Reputation: 114310

That's just how importing works, as documented: https://docs.python.org/3/tutorial/modules.html#more-on-modules. Specifically:

A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module name is encountered in an import statement.

Basically, the import statement first checks if sys.modules contains your module already. If it does, the existing reference is returned, as in your second case. If not, an empty module object is created, added to sys.modules, and only then populated by running the .py file. The reason for doing it this way is to avoid loops from circular imports: a module won't be reloaded in such a loop, even if it's object is still empty.

The references to global_variable in all three files point to the exact same object. You can check in file_a by adding the following to the existing code:

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)

One caveat to keep in mind is that running a module as a script will place it in sys.modules under the name __main__. Any code that tries to import it under its usual name will load a different module object, sometimes leading to unexpected consequences.

Upvotes: 4

Priyatham
Priyatham

Reputation: 2897

Python caches imports in sys.modules. So even if you import the same module multiple times, it will use the cached versions instead of repeatedly importing.

Read about the module cache for more information.

Upvotes: 3

Related Questions