25

I suppose this is a general question so sorry if not posted in the right place.

Say for instance, I have a function a which imports os. If I was to call this function from another file multiple times I am assuming that the import would be done multiple times as well? Is there a way to only import the module if its not already present?

Basically, I have a class which calls multiple functions imported from various files, instead of importing the whole file I thought it would be easier to import just the function but now I am wondering if I am going to give myself headaches in the long run with excess imports.

Dmitry Ermolov
  • 2,077
  • 1
  • 15
  • 24
JONAS402
  • 591
  • 1
  • 9
  • 18
  • The biggest question is why are you importing inside the function and not at the top of the file? There's almost no reason to do that and doing so is a code smell. – Two-Bit Alchemist May 06 '16 at 12:22
  • 10
    Python cache imported modules and doesn't import them twice. – Sergey Gornostaev May 06 '16 at 12:22
  • 1
    i was importing just a function from the module, so to avoid errors i included the imports in the function, im assuming i should import the whole file and just call the function as normal? – JONAS402 May 06 '16 at 12:37
  • 1
    Importing "just a function" from a module still executes all the module's code if the module hasn't previously been loaded. You don't need to move imports into the function to guarantee they'll happen. – user2357112 May 06 '16 at 17:35
  • 2
    Actually, if your question was the opposite, then you'd have to do some special case handling with *reload(os)* to force it to be imported again. But as it is and as other answers state, you're already covered. As far as @Two-BitAlchemist 's remark goes, he's correct as well. Though sometimes doing so avoid issues with circular module references (still a code smell). – JL Peyret May 06 '16 at 18:42

1 Answers1

78

As described in the python documentation, when python see some import statement it does the following things:

  • checks some global table if the module is already imported
    • if the module is not there, python imports it, creates a module object and puts the newly created module object in the global table
    • if the module is there, python just gets module object
  • when python has the module object, it binds it to the name you chose
    • if it was import foo, the name for the module foo will be foo
    • if it was import foo as bar, the name for the module foo will be bar
    • if it was from foo import bar as baz, python finds the function (or whatever) bar in module foo and will bind this function to the name baz

So each module is imported only one time.

To better understand import mechanics, I would suggest creating a toy example.

File module.py:

print("import is in progress")

def foo():
    pass

File main.py:

def foo():
    print("before importing module")
    import module
    module.foo()
    print("after importing module")
 
if __name__ == '__main__':
    foo()
    foo()

Put the above files in the same directory. When module.py is being imported, it prints import is in progress. When you launch main.py, it will try to import module several times but the output will be:

before importing module
import is in progress
after importing module
before importing module
after importing module

So import really happens only once. You can adjust this toy example to check cases that are interesting to you.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Dmitry Ermolov
  • 2,077
  • 1
  • 15
  • 24
  • 2
    Great, very clear. Just one more thing need to be carefule. If later you import module to a with **as** like `from module import foo as new_name`, the previous module name would be coverd shows `global name 'module' is not defined` – maroon912 May 19 '17 at 09:03
  • Same mechanism for JavaScript. – heLomaN May 08 '23 at 11:15