Now that you know a lot about functions, let's see how to use them. The whole point of writing functions is to be able to later reuse them, and this in Python translates to importing them into the namespace in which you need them. There are many different ways to import objects into a namespace, but the most common ones are just two: import module_name
and from module_name import function_name
. Of course, these are quite simplistic examples, but bear with me for the time being.
The form import module_name
finds the module module_name
and defines a name for it in the local namespace where the import
statement is executed.
The form from module_name import identifier
is a little bit more complicated than that, but basically does the same thing. It finds module_name
and searches for an attribute (or a submodule) and stores a reference to identifier
in the local namespace.
Both forms have the option to change the name of the imported object using the as
clause, like this:
from mymodule import myfunc as better_named_func
Just to give you a flavor of what importing looks like, here's an example from a test module of a number theory library I wrote some years ago (it's available on Bitbucket):
karma/test_nt.py
import unittest # imports the unittest module from math import sqrt # imports one function from math from random import randint, sample # two imports at once from mock import patch from nose.tools import ( # multiline import assert_equal, assert_list_equal, assert_not_in, ) from karma import nt, utils
I commented some of them and I hope it's easy to follow. When you have a structure of files starting in the root of your project, you can use the dot notation to get to the object you want to import into your current namespace, be it a package, a module, a class, a function, or anything else. The from module import
syntax also allows a catch-all clause from module import *
, which is sometimes used to get all the names from a module into the current namespace at once, but it's frowned upon for several reasons: performances, the risk of silently shadowing other names, and so on. You can read all that there is to know about imports in the official Python documentation but, before we leave the subject, let me give you a better example.
Imagine that you have defined a couple of functions: square(n)
and cube(n)
in a module, funcdef.py
, which is in the lib
folder. You want to use them in a couple of modules which are at the same level of the lib
folder, called func_import.py
, and func_from.py
. Showing the tree structure of that project produces something like this:
├── func_from.py ├── func_import.py ├── lib ├── funcdef.py └── __init__.py
Before I show you the code of each module, please remember that in order to tell Python that it is actually a package, we need to put a __init__.py
module in it.
funcdef.py
def square(n): return n ** 2 def cube(n): return n ** 3
func_import.py
import lib.funcdef
print(lib.funcdef.square(10))
print(lib.funcdef.cube(10))
func_from.py
from lib.funcdef import square, cube
print(square(10))
print(cube(10))
Both these files, when executed, print 100
and 1000
. You can see how differently we then access the square
and cube
functions, according to how and what we imported in the current scope.
The imports we've seen until now are called absolute, that is to say they define the whole path of the module that we want to import, or from which we want to import an object. There is another way of importing objects into Python, which is called relative import. It's helpful in situations in which we want to rearrange the structure of large packages without having to edit sub-packages, or when we want to make a module inside a package able to import itself. Relative imports are done by adding as many leading dots in front of the module as the number of folders we need to backtrack, in order to find what we're searching for. Simply put, it is something like this:
from .mymodule import myfunc
For a complete explanation of relative imports, refer to PEP328 (https://www.python.org/dev/peps/pep-0328).
In later chapters, we'll create projects using different libraries and we'll use several different types of imports, including relative ones, so make sure you take a bit of time to read up about it in the official Python documentation.