Modules, packages and imports
Motivations: import code from other files¶
Useful for:
reusing code
organizing code
distributing code (not detailed here)
Multi-file program and imports¶
Simple case of a directory with 2 files¶
Let’s study this very simple “package” (i.e. a directory) containing 2 files:
import os
os.listdir("../common/examples/example0")['prog.py', 'util.py']The file util.py contains:
print("begin of util.py")
myvar0 = 0
myvar1 = 1
def print_variables():
print(f"in function print_variables: {myvar0 = }; {myvar1 = }")
Let’s run it:
%run ../common/examples/example0/util.pybegin of util.py
The file prog.py contains:
print("in prog.py (before imports)")
# 2 different syntaxes for importing a module
import util
from util import myvar1, print_variables
util.myvar0 = 100
myvar1 += 100
print(f"in prog.py (after imports), {util.myvar0 = }; {myvar1 = }")
print_variables()
Let’s run it:
%run ../common/examples/example0/prog.pyin prog.py (before imports)
begin of util.py
in prog.py (after imports), util.myvar0 = 100; myvar1 = 101
in function print_variables: myvar0 = 100; myvar1 = 1
More advanced notions¶
In the directory example1, we also have 2 files:
os.listdir("../common/examples/example1")['prog.py', 'util.py']The files are just slightly modified versions of the files in
../common/examples/example0. The goal is to try to understand:
the very common idiom
if __name__ == "__main__": ....where the Python interpreters looks for module and the attribute
sys.path.
../common/examples/example1/util.py contains:
print("begin of util.py")
myvar0 = 0
myvar1 = 1
def print_variables():
print(f"in function print_variables: {myvar0 = }; {myvar1 = }")
print(f"in util.py, {__name__ =}")
# __name__ is a special variable always defined in a Python file.
# its value depends on how the file is called (directly executed or imported)
if __name__ == "__main__":
# this code is executed only in the file is directly executed
print("the module util.py has been directly executed")
print_variables()
print("end of util.py")
else:
# usually, we do nothing particular for this case (file imported)
print("the module util.py has been imported")
Let’s study what it gives when one executes it directly:
%run ../common/examples/example1/util.pybegin of util.py
in util.py, __name__ ='__main__'
the module util.py has been directly executed
in function print_variables: myvar0 = 0; myvar1 = 1
end of util.py
And ../common/examples/example1/prog.py contains:
print("in prog.py (before imports)")
import sys
from pprint import pprint
# 2 different syntaxes for importing a module
import util
from util import myvar1, print_variables
print("sys.path[:4]:")
pprint(sys.path[:4])
util.myvar0 = 100
myvar1 += 100
print(f"in prog.py (after imports), {util.myvar0 = }; {myvar1 = }")
print_variables()
Let’s run it:
%run ../common/examples/example1/prog.pyin prog.py (before imports)
sys.path[:4]:
['/builds/py-edu-fr/py-edu-fr/src/common/examples/example1',
'/usr/local/lib/python313.zip',
'/usr/local/lib/python3.13',
'/usr/local/lib/python3.13/lib-dynload']
in prog.py (after imports), util.myvar0 = 100; myvar1 = 101
in function print_variables: myvar0 = 100; myvar1 = 1
Warning about syntax from ... import *¶
There is another import syntax, with a star:
from matplotlib.pylab import *It imports in the global namespace all names of the namespace matplotlib.pylab. It can
be useful in some situations but should be avoid in many cases. With this syntax, you
don’t know from where come the names and automatic code analysis becomes much more
difficult.
Standard structure of a Python module¶
"""A program...
Documentation of the module.
"""
# import functions, modules and/or classes
from math import sqrt
# definition of functions and/or classes
def mysum(variables):
"""sum all the variables of the function and return it.
No type check
:param variables: (iterable) an iterable over elements
that can be summed up
:return: the sum of the variables
"""
result = 0
for var in variables:
result += var
return result
def main():
l = [1, 2, 3, 4]
print("the square of mysum(l) is", sqrt(mysum(l)))
# main part of the program (protected)
if __name__ == "__main__":
main()the square of mysum(l) is 3.1622776601683795