What's the difference between a Python module and a Python package?
Any Python file is a module, its name being the file's base name without the
.py extension. A package is a collection of Python modules: while a module is a single Python file, a package is a directory of Python modules containing an additional
__init__.py file, to distinguish a package from a directory that just happens to contain a bunch of Python scripts. Packages can be nested to any depth, provided that the corresponding directories contain their own
The distinction between module and package seems to hold just at the file system level. When you import a module or a package, the corresponding object created by Python is always of type
module. Note, however, when you import a package, only variables/functions/classes in the
__init__.py file of that package are directly visible, not sub-packages or modules. As an example, consider the
xml package in the Python standard library: its
xml directory contains an
__init__.py file and four sub-directories; the sub-directory
etree contains an
__init__.py file and, among others, an
ElementTree.py file. See what happens when you try to interactively import package/modules:
import xmltype(xml)<type 'module'> xml.etree.ElementTreeTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'module' object has no attribute 'etree'import xml.etreetype(xml.etree)<type 'module'> xml.etree.ElementTreeTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'module' object has no attribute 'ElementTree'import xml.etree.ElementTreetype(xml.etree.ElementTree)<type 'module'> xml.etree.ElementTree.parse<function parse at 0x00B135B0>
In Python there also are built-in modules, such as
sys, that are written in C, but I don't think you meant to consider those in your question.
A module is a single file (or files) that are imported under one import and used.e.g.
A package is a collection of modules in directories that give a package hierarchy.
from my_package.timing.danger.internets import function_of_love
First, keep in mind that, in its precise definition, a module is an object in the memory of a Python interpreter, often created by reading one or more files from disk. While we may informally call a disk file such as
a/b/c.py a "module," it doesn't actually become one until it's combined with information from several other sources (such as
sys.path) to create the module object.
(Note, for example, that two modules with different names can be loaded from the same file, depending on
sys.path and other settings. This is exactly what happens with
python -m my.module followed by an
import my.module in the interpreter; there will be two module objects,
my.module, both created from the same file on disk,
A package is a module that may have submodules (including subpackages). Not all modules can do this. As an example, create a small module hierarchy:
$ mkdir -p a/b$ touch a/b/c.py
Ensure that there are no other files under
a. Start a Python 3.4 or later interpreter (e.g., with
python3 -i) and examine the results of the following statements:
import aa ⇒ <module 'a' (namespace)>a.b ⇒ AttributeError: module 'a' has no attribute 'b'import a.b.ca.b ⇒ <module 'a.b' (namespace)>a.b.c ⇒ <module 'a.b.c' from '/home/cjs/a/b/c.py'>
a.b are packages (in fact, a certain kind of package called a "namespace package," though we wont' worry about that here). However, module
a.b.c is not a package. We can demonstrate this by adding another file,
a/b.py to the directory structure above and starting a fresh interpreter:
import a.b.c⇒ ImportError: No module named 'a.b.c'; 'a.b' is not a packageimport a.ba ⇒ <module 'a' (namespace)>a.__path__ ⇒ _NamespacePath(['/.../a'])a.b ⇒ <module 'a.b' from '/home/cjs/tmp/a/b.py'>a.b.__path__ ⇒ AttributeError: 'module' object has no attribute '__path__'
Python ensures that all parent modules are loaded before a child module is loaded. Above it finds that
a/ is a directory, and so creates a namespace package
a, and that
a/b.py is a Python source file which it loads and uses to create a (non-package) module
a.b. At this point you cannot have a module
a.b is not a package, and thus cannot have submodules.
You can also see here that the package module
a has a
__path__ attribute (packages must have this) but the non-package module
a.b does not.