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.py
un "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.path
y otras configuraciones. Esto es exactamente lo que sucede con python -m my.module
seguido de un import my.module
en 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 a
y a.b
paquetes (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.c
no es un paquete. Podemos demostrar esto agregando otro archivo a/b.py
a 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.py
es 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.c
porque a.b
no es un paquete y, por lo tanto, no puede tener submódulos.
También puede ver aquí que el módulo de paquete a
tiene un __path__
atributo (los paquetes deben tener esto) pero el módulo sin paquete a.b
no.