Primero, tenga en cuenta que, en su definición precisa, un módulo es un objeto en la memoria de un intérprete de Python, a menudo creado al leer uno o más archivos del disco. Si bien podemos llamar informalmente un archivo de disco como a/b/c.pyun "módulo", en realidad no se convierte en uno hasta que se combina con información de varias otras fuentes (como sys.path) para crear el objeto del módulo.
(Tenga en cuenta, por ejemplo, que se pueden cargar dos módulos con nombres diferentes desde el mismo archivo, dependiendo de sys.pathy otras configuraciones. Esto es exactamente lo que sucede con python -m my.moduleseguido de un import my.moduleen el intérprete; habrá dos objetos de módulo __main__y my.module, ambos creados) del mismo archivo en el disco,. my/module.py)
Un paquete es un módulo que puede tener submódulos (incluidos los subpaquetes). No todos los módulos pueden hacer esto. Como ejemplo, cree una pequeña jerarquía de módulos:
$ mkdir -p a/b
$ touch a/b/c.py
Asegúrese de que no haya otros archivos debajo a. Inicie un intérprete Python 3.4 o posterior (por ejemplo, con python3 -i) y examine los resultados de las siguientes afirmaciones:
import a
a ⇒ <module 'a' (namespace)>
a.b ⇒ AttributeError: module 'a' has no attribute 'b'
import a.b.c
a.b ⇒ <module 'a.b' (namespace)>
a.b.c ⇒ <module 'a.b.c' from '/home/cjs/a/b/c.py'>
Módulos ay a.bpaquetes (de hecho, cierto tipo de paquete llamado "paquete de espacio de nombres", aunque no nos preocuparemos por eso aquí). Sin embargo, el módulo a.b.cno es un paquete. Podemos demostrar esto agregando otro archivo a/b.pya la estructura de directorios anterior e iniciando un nuevo intérprete:
import a.b.c
⇒ ImportError: No module named 'a.b.c'; 'a.b' is not a package
import a.b
a ⇒ <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 asegura que todos los módulos principales se carguen antes de cargar un módulo secundario. Arriba encuentra que a/es un directorio y, por lo tanto, crea un paquete de espacio de nombres a, y que a/b.pyes un archivo fuente de Python que carga y usa para crear un módulo (sin paquete) a.b. En este punto, no puede tener un módulo a.b.cporque a.bno es un paquete y, por lo tanto, no puede tener submódulos.
También puede ver aquí que el módulo de paquete atiene un __path__atributo (los paquetes deben tener esto) pero el módulo sin paquete a.bno.