Modules¶
Définition et importation¶
Un module est un ensemble de définitions d’objets placé dans un fichier (d’extension py
).
Supposons que l’on souhaite écrire un module pour définir des fonctions permettant de faire des calculs sur le rayonnement du corps noir. Pour ce faire, on enregistre dans un fichier nommé corpsnoir.py
le code suivant :
1 2 3 4 5 6 7 8 9 10 11 | import numpy
h=6.626e-34 # constante de Planck
c=299792458.0 # vitesse de la lumière
k=1.38e-23 # constante de Boltzmann
def exitance(L,T):
# L : longueur d'onde en micromètres
# T : température en Kelvin
L = L*1e-6
return 2*numpy.pi*h*c**2/(L**5*(numpy.exp(h*c/(L*k*T))-1))*1e-6
|
Ce module comporte trois définitions d’objets de type float
et une définition de fonction, avec bien sûr des noms associés.
Un module doit être importé dans le script où on veut l’utiliser, ou bien depuis la console. L’importation se fait par l’instruction suivante :
>>> import corpsnoir
Il faut que l’interpréteur de Python trouve le fichier. Il effectue sa recherche dans une liste de chemins, consultable par :
>>> import sys
>>> sys.path
Le répertoire de travail est le premier de la liste. Si le fichier se trouve dans le répertoire de travail, il peut donc être importé. On remarque par ailleurs que le module importe lui-même un autre module, nommé numpy
, qui se trouve dans un répertoire de la distribution Python utilisée.
Dès lors que le module est importé, les noms qu’il définit sont accessibles par la syntaxe suivante :
>>> corpsnoir.h
6.626e-34
>>> corpsnoir.exitance(500,1000)
0.00040995221937790315
Les noms définis dans le module ne sont pas dans l’espace de noms global, mais sont accessibles via la notation corpsnoir.
(le nom du module suivi d’un point). Il y a ainsi séparation entre l’espace des noms courant et l’espace des noms du module, ce qui est une très bonne chose.
L’inconvénient est l’obligation de placer le nom du module en préfixe de chaque nom. La tâche peut être allégée en introduisant un alias, c’est-à-dire un nom abrégé qui vient remplacer le nom complet, par exemple :
>>> import corpsnoir as cn
>>> cn.h
6.626e-34
Il est possible d’importer des noms dans l’espace de noms courant, mais il faut le faire avec prudence, car cet espace de noms peut contenir déjà des noms identiques à certains noms du module, ce qui viendrait détruire les premiers. Il est donc préférable d’importer dans l’espace de noms courant seulement les noms dont on a besoin :
>>> from corpsnoir import exitance
>>> exitance(500,1000)
0.00040995221937790315
En principe, il vaut mieux éviter ce type d’importation. Il est d’ailleurs possible de faire pire en important dans l’espace de noms courant tous les noms du module :
>>> h = 100
>>> from corpsnoir import *
>>> h
6.626e-34
Comme on le voit sur cet exemple, le nom h
dont la déclaration précède l’importation du module et qui pointait vers un entier de valeur 100, est remplacé par la variable définie dans le module, ce qui signifie que le même nom fait finalement référence à un flottant de valeur 6.626e-34
. Pour éviter ce genre de désagrément (dont les conséquences peuvent être désastreuses), il est préférable de ne jamais importer de noms dans l’espace de noms courant.
Notons que le contenu d’un module peut être obtenu par la fonction dir
(le module doit être déjà importé) :
>>> dir(corpsnoir)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'exitance', 'h', 'k', 'numpy']
Ce module importe lui-même un module, nommé numpy
, dont il a besoin pour faire ses calculs. Cependant, celui-ci serait accessible par la syntaxe corpsnoir.numpy
, qui n’a pas de sens puisque le module numpy ne fait pas partie du module corpsnoir.
Exemple : module math¶
On appelle bibilothèque (library en anglais) un ensemble de modules, mais la notion de bibliothèque ne correspond à rien de précis en Python.
Le logiciel Python est livré avec une bibliothèque appelée bibliothèque standard. Cette bibliothèque est donc présente dans toutes les distributions de Python, même les plus petites.
La bibliothèque standard comporte des modules qui répondent à des besoins très généraux et très variés. Leur liste, ainsi que leur documentation complète, est consultable sur https://docs.python.org/fr/3/library/index.html
Nous nous intéressons en particulier au module math
, qui comporte des fonctions mathématiques d’usage courant. Voici par exemple comment se servir de ce module pour calculer un cosinus :
>>> import math
>>> math.pi
3.141592653589793
>>> math.cos(math.pi*0.5)
6.123233995736766e-17
On remarque au passage que le résultat de ce calcul est affecté d’une erreur d’arrondi, puisque le résultat exact est 0.
Paquet¶
Un paquet (en anglais package) est une organisation hiérarchique de plusieurs modules, qui prend la forme d’une arborescence.
Supposons que l’on souhaite créer un paquet nommé thermo
qui contiendrait le module corpsnoir
et d’autres modules destinés à faire des calculs dans différents domaines de la thermodynamique. Afin de réaliser un paquet dit classique, nous devons créer l’arborescence de fichiers suivante
thermo/
__init__.py
corpsnoir
__init__.py
gazparfait
__init__.py
fluides
__init__.py
etc.
Chaque sous-dossier constitue un module (en fait un sous-module). Le fichier __init__.py contient le code python qui est exécuté lors de l’importation du module. Dans le cas présent, il faut placer le contenu du fichier corpsnoir.py
précédent dans le fichier __init__.py
du dossier corpsnoir
.
L’importation du module se fait de la manière suivante :
>>> import thermo.corpsnoir
ou bien avec un alias :
>>> import thermo.corpsnoir as cn
Le fichier __init__.py
du dossier thermo
constitue également un module, le module racine du paquet, où on placerait des définitions générales de la thermodynamique, et qui serait importé par :
>>> import thermo
Cependant, cette dernière importation n’importe pas les sous-modules. Ceux-ci doivent être importés explicitement.
Les bibliothèques de grande taille sont généralement organisées sous forme de paquets. Les bibliothèques les plus importantes pour le calcul numérique sont numpy
, matplolib
et scipy
.
On peut par exemple importer numpy
:
>>> import numpy
Ce module apporte les fonctions de base pour créer et manipuler des tableaux numériques. Si l’on souhaite en plus générer des tableaux contenant des nombres aléatoires, il faudra faire l’importation suivante :
>>> import numpy.random