This is an archived version of the course. Please find the latest version of the course on the main webpage.

Chapter 8: Python packages

Regular packages

Before Python version 3.3, all packages are regular packages. This is a more traditional form of packages where all files from the package are in the same hard drive location.

To turn a directory into a regular package, you include an __init__.py file in the directory. The __init__.py file is usually just an empty file, but may also contain some initialisation code, or can be used to set some magic variables (more on this later).

sound/
    __init__.py
    formats/
        __init__.py
        wavread.py
        wavwrite.py
        ...
    effects/
        __init__.py
        echo.py
        surround.py
        ...
    filters/
        __init__.py
        equalizer.py
        vocoder.py
        ...

Before Python 3.3, if you do not include __init__.py, for example inside formats/, then you will not be able to import sound.formats since sound.formats is not a package (it’s just a directory).

From Python 3.3 onwards, __init__.py has become optional, so import sound.formats works directly. Without __init__.py, sound.formats becomes a namespace package (as discussed in the previous page). With __init__.py, it becomes a traditional regular package.

But beware! If you create a regular package, then it cannot be a namespace package at the same time. So the example from the previous page will not work! Python will only recognise wavread.py, even if you have added site2 to sys.path. This is because site1 is now a regular package and cannot be ‘spread’ across different locations.

main.py
site1/
    sound/
        formats/
            __init__.py
            wavread.py
site2/
    sound/
        formats/
            wavwrite.py
>>> import sys
>>> sys.path.append("site1")
>>> sys.path.append("site2")
>>> from sound.formats import wavread, wavwrite
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'wavwrite' from 'sound.formats' (/xx/xx/xx/xx/site1/sound/formats/__init__.py)