Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When importing, why is the entire module loaded even when only specific portions are specified?

Tags:

python

I'm trying to get my programs memory footprint under control. I thought I'd start with the imports, as I'm only using 3-4 functions out of the rather large PyObjC library. However, I was a little surprised to see that importing specific pieces of a larger module had zero bearing on what was actually loaded into memory.

Memory Profiler output

loading the entire Quartz.CoreGraphics library on OSX:

Line #    Mem usage    Increment   Line Contents
================================================
    77                             @profile 
    78     7.953 MB     0.000 MB   def test_import_all():
    79    26.734 MB    18.781 MB    import Quartz.CoreGraphics as CG

It pulls in the entire library at almost 19MB.

Trying to only pull in what I need gives the same 19MB results:

Line #    Mem usage    Increment   Line Contents
================================================
    82                             @profile
    83     7.941 MB     0.000 MB   def test_import_some():
    84    26.727 MB    18.785 MB    from Quartz.CoreGraphics import CGImageGetWidth 

So, it seems that specific imports have no bearing on what actually gets loaded.

Needing only a small handful of functions from an otherwise huge module seems like it would be a common use-case. Is there any way to load only what I need from a module into memory, or is this just the consequence of using external libraries?

like image 770
Zack Yoshyaro Avatar asked Sep 16 '13 19:09

Zack Yoshyaro


People also ask

Why is Python running my module when I import it?

This happens because when Python imports a module, it runs all the code in that module. After running the module it takes whatever variables were defined in that module, and it puts them on the module object, which in our case is salutations .

What happens when a module is imported?

When a module is first imported, Python searches for the module and if found, it creates a module object 1, initializing it. If the named module cannot be found, a ModuleNotFoundError is raised. Python implements various strategies to search for the named module when the import machinery is invoked.

How many times does a module gets loaded when imported multiple times?

The import Statement A module is loaded only once, regardless of the number of times it is imported. This prevents the module execution from happening over and over again if multiple imports occur.

How does importing modules work in Python?

In Python, you use the import keyword to make code in one module available in another. Imports in Python are important for structuring your code effectively. Using imports properly will make you more productive, allowing you to reuse code while keeping your projects maintainable.


1 Answers

That's just how module loading works. The runtime maintains a collection of loaded modules, so the whole module is reachable even if you've only imported a few symbols. This has two desirable consequences:

  • future imports of the same module are fast.
  • any code at module-level that has side-effects, is executed only once (barring a module reload) instead of being executed a variable number of times depending what bits of the module are imported in what places.

It's also fairly inevitable if you consider that any function in the module can access the module namespace, either directly by using names from it or indirectly via globals(), sys.modules[__name__], eval, or whatever. So barring some clever optimization to prove that particular functions don't do this (which Python implementations don't generally bother with), the whole module namespace has to be in memory.

like image 159
Steve Jessop Avatar answered Sep 22 '22 19:09

Steve Jessop