Tout d'abord, gardez à l'esprit que, dans sa définition précise, un module est un objet dans la mémoire d'un interpréteur Python, souvent créé en lisant un ou plusieurs fichiers à partir du disque. Bien que nous puissions appeler de manière informelle un fichier disque tel a/b/c.py
qu'un "module", il ne le devient en réalité que lorsqu'il est combiné avec des informations provenant de plusieurs autres sources (telles que sys.path
) pour créer l'objet module.
(Note, par exemple, que les deux modules avec des noms différents peuvent être chargés à partir du même fichier, en fonction sys.path
et d' autres paramètres est exactement ce qui se passe avec. python -m my.module
Suivi d'un import my.module
à l'interprète, il y aura deux objets de module, __main__
et my.module
, à la fois créé du même fichier sur le disque,. my/module.py
)
Un package est un module qui peut avoir des sous-modules (y compris des sous-packages). Tous les modules ne peuvent pas le faire. Par exemple, créez une petite hiérarchie de modules:
$ mkdir -p a/b
$ touch a/b/c.py
Assurez-vous qu'il n'y a pas d'autres fichiers sous a
. Démarrez un interpréteur Python 3.4 ou version ultérieure (par exemple, avec python3 -i
) et examinez les résultats des instructions suivantes:
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'>
Les modules a
et a.b
sont des packages (en fait, un certain type de package appelé «package d'espace de noms», bien que nous ne nous en préoccupions pas ici). Cependant, le module a.b.c
n'est pas un package. Nous pouvons le démontrer en ajoutant un autre fichier a/b.py
à la structure de répertoires ci-dessus et en démarrant un nouvel interpréteur:
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 garantit que tous les modules parents sont chargés avant le chargement d'un module enfant. Au-dessus, il trouve qu'il a/
s'agit d'un répertoire, et crée donc un package d'espace de noms a
, et c'est a/b.py
un fichier source Python qu'il charge et utilise pour créer un module (non-package) a.b
. À ce stade, vous ne pouvez pas avoir de module a.b.c
car il a.b
ne s'agit pas d'un package et ne pouvez donc pas avoir de sous-modules.
Vous pouvez également voir ici que le module de package a
a un __path__
attribut (les packages doivent en avoir) mais pas le module non-package a.b
.