Modules and Packages

Modules

  • Collection of … well … objects - e.g. classes, functions, variables

  • Collected in a dedicated .py file

  • Pulled in with the import statement

import sys

So where is sys looked for?

  • In the directory where the importer lives

  • Along the PYTHONPATH environment variable

  • In the Python installation’s module directories

Modules are Objects

  • import makes a module object available under a name

  • ⟶ a variable

  • Contained names accessible through that variable

  • ⟶ “Namespace”

import sys
...
sys.exit(42)

Other Forms (1)

Pulling in a single symbol
from sys import exit
exit(42)
Massacre …
from sys import *
exit(42)
  • Pulls in everything into the importer’s namespace

    • Well, except those names that start with an underscore

  • Conflicts easily possible

  • Importer’s names are overwritten with conflicting names

Other Forms (2)

Changing a module’s name
import sys
my_sys = sys
del sys
Shorter …
import sys as my_sys
Same with specific imports
from sys import exit as my_exit
my_exit(42)

Packages

  • Package: collection of modules (and further packages)

  • “Subnamespace”

import os.path
path = os.path.normpath('a/../b')
from os.path import normpath

Executing Modules as Scripts

  • A module’s name is its filename, with the .py extension stripped

  • Available to the module in the variable __name__

  • Can be used to decide if the module is being imported or executed as a script

Inside mysupermodule.py
def mysuperfunction(a, b):
    ...

if __name__ == '__main__':
    mysuperfunction(sys.argv[1], sys.argv[2]))

Package Structure

package/
+-- __init__.py
+-- subpackage1
|   +-- __init__.py
|   +-- module1.py
|   \- module2.py
\- subpackage2
    +-- __init__.py
    +-- module1.py
    \-- module2.py
  • Top level directory package/ found in module search path

  • Each directory has file __init__.py

    • Disambiguation

    • Usually empty

Relative Imports (1)

package/
+-- subpackage1
    +-- module1.py
    \- module2.py

Problem: inside module1.py, I want to …

  • import module2

  • Not search along the entire module search path

  • I know that module2 is next to me

from . import module2

Relative Imports (2)

package/
+-- subpackage1
    \-- module1.py
\- subpackage2
    \-- module1.py

Problem:

  • subpackage1/module1.py wants to import subpackage2/module1.py

  • … and nothing else

from ..subpackage2 import module1