Created by: gwideman, Mar 14, 2011 5:17 am
Revised by: gwideman, Nov 5, 2013 3:25 pm (5 revisions)

Table of Contents


NOTE 2013-11-05: The following description is for Python <= 3.2x. For Python 3.3, PEP 420 came into effect, allowing directories (on sys.path) to be considered as packages even if lacking an __init__.py file. I have not fully considered the implications of that, and it's not factored into the discussion below.

Overview

Summary of points about the structure of Python packages. Reflects what I think I know about Python 3.x.

Package structure

Two units of code which Python recognizes:
  • Module
    • A text file located in a directory that's included in sys.path.
    • Name of file (minus an optional extension of ".py") is the module name.
    • A module can contain variables, functions definitions, class definitions (etc). Those declared at the top level of the module (not enclosed in a class or function etc) are "attributes of the module"
      • All top level attributes of module are public, that is accessible by other modules. There is a convention that attributes whose names have a leading underscore are to be considered "private", but Python does not enforce this.
    • A module can use the import statement to reference another module and its attributes
    • If a module is run from the OS (or IDE debugger) then it plays the role of "main module".
  • Package
    • Consists of:
      • Package directory located in a directory that's included in sys.path
      • The directory name becomes the package name.
      • The package directory contains
        • A file named __init__.py Presence of this file flags the directory as a package (assuming it's on sys.path).
          • That file can be empty
          • Can include code just like a normal module.
          • It is loaded and executed the first time the package (or some subsidiary module) is imported by some calling module (using the import statement).
          • Can selectively expose the member modules and code
            • Can explicitly import other modules in the package, which exposes those modules to callers who import just the package.
            • Could omit explicit imports, requiring caller to import them explicitly.
            • Can use the __all__ variable
            • Question: Does __all__ work only in conjunction with the from xxx import * statement, or does it work generally to specify (and thus limit) attribute visibility?
              • Answer: Only affects the from xxx import * statement.
        • Other module files (member modules)
        • Subsidiary directories with modules
          • Question: Must subdirs have their own __init__.py files?
            • Answer: Yes, at least in my tests of Python 3.x. (I have seen books about 2.x Python asserting that some 2.x versions did not require subdirs to have __init__.py)