Modules

Python modules are one of the main abstraction layers available and probably themost natural one. Abstraction layers allow separating code into parts holdingrelated data and functionality.

For example, a layer of a project can handle interfacing with user actions,while another would handle low-level manipulation of data. The most natural wayto separate these two layers is to regroup all interfacing functionalityin one file, and all low-level operations in another file. In this case,the interface file needs to import the low-level file. This is done with theimport and from import statements.

As soon as you use import statements you use modules. These can be eitherbuilt-in modules such as os and sys, third-party modules you have installedin your environment, or your project’s internal modules.

To keep in line with the style guide, keep module names short, lowercase, andbe sure to avoid using special symbols like the dot (.) or question mark (?).So a file name like my.spam.py is one you should avoid! Naming this waywill interfere with the way Python looks for modules.

In the case of my.spam.py Python expects to find a spam.py file in afolder named my which is not the case. There is anexample of how thedot notation should be used in the Python docs.

If you’d like you could name your module my_spam.py, but even ourfriend the underscore should not be seen often in module names. However, using othercharacters (spaces or hyphens) in module names will prevent importing(- is the subtract operator), so try to keep module names short so there isno need to separate words. And, most of all, don’t namespace with underscores; use submodules instead.

  1. # OK
  2. import library.plugin.foo
  3. # not OK
  4. import library.foo_plugin

Aside from some naming restrictions, nothing special is required for a Pythonfile to be a module, but you need to understand the import mechanism in orderto use this concept properly and avoid some issues.

Concretely, the import modu statement will look for the proper file, whichis modu.py in the same directory as the caller if it exists. If it isnot found, the Python interpreter will search for modu.py in the “path”recursively and raise an ImportError exception if it is not found.

Once modu.py is found, the Python interpreter will execute the module inan isolated scope. Any top-level statement in modu.py will be executed,including other imports if any. Function and class definitions are stored inthe module’s dictionary.

Then, the module’s variables, functions, and classes will be available to thecaller through the module’s namespace, a central concept in programming that isparticularly helpful and powerful in Python.

In many languages, an include file directive is used by the preprocessor totake all code found in the file and ‘copy’ it into the caller’s code. It isdifferent in Python: the included code is isolated in a module namespace, whichmeans that you generally don’t have to worry that the included code could haveunwanted effects, e.g. override an existing function with the same name.

It is possible to simulate the more standard behavior by using a special syntaxof the import statement: from modu import . This is generally consideredbad practice. Using import makes code harder to read and makesdependencies less compartmentalized.

Using from modu import func is a way to pinpoint the function you want toimport and put it in the local namespace. While much less harmful than import
*
because it shows explicitly what is imported in the local namespace, itsonly advantage over a simpler import modu is that it will save a littletyping.

Very bad

  1. [...]
  2. from modu import *
  3. [...]
  4. x = sqrt(4) # Is sqrt part of modu? A builtin? Defined above?

Better

  1. from modu import sqrt
  2. [...]
  3. x = sqrt(4) # sqrt may be part of modu, if not redefined in between

Best

  1. import modu
  2. [...]
  3. x = modu.sqrt(4) # sqrt is visibly part of modu's namespace

As mentioned in the Code Style section, readability is one of the mainfeatures of Python. Readability means to avoid useless boilerplate text andclutter; therefore some efforts are spent trying to achieve a certain level ofbrevity. But terseness and obscurity are the limits where brevity should stop.Being able to tell immediately where a class or function comes from, as in themodu.func idiom, greatly improves code readability and understandability inall but the simplest single file projects.