Les Modules Python
Qu'est-ce qu'un module ?
Un module est simplement un fichier .py contenant des fonctions, des classes et des variables. Les modules permettent d'organiser le code en unites logiques reutilisables et d'eviter de tout mettre dans un seul fichier gigantesque.
Python dispose d'une bibliotheque standard tres riche : des centaines de modules prets a l'emploi couvrant les maths, les dates, les fichiers, le reseau, les expressions regulieres, et bien plus encore.
# mon_module.py (ceci est un module)
PI = 3.14159
def aire_cercle(rayon):
return PI * rayon ** 2
def perimetre_cercle(rayon):
return 2 * PI * rayon
Importer un module : import
La facon la plus simple d'utiliser un module est de l'importer avec import :
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(25)) # 5.0
print(math.floor(3.7)) # 3
print(math.ceil(3.2)) # 4
Apres import math, toutes les fonctions et variables du module sont accessibles via la syntaxe math.nom.
Importer une fonction specifique : from ... import
Si vous n'avez besoin que d'une ou deux fonctions, vous pouvez les importer directement :
from math import sqrt, pi
print(sqrt(49)) # 7.0
print(pi) # 3.141592653589793
# Plus besoin d'ecrire math.sqrt ou math.pi
Cela evite de taper le nom du module a chaque fois.
Alias : import ... as
Vous pouvez renommer un module lors de l'import pour raccourcir son nom :
import datetime as dt
import collections as col
maintenant = dt.datetime.now()
print(maintenant)
compteur = col.Counter([1, 2, 2, 3, 3, 3])
print(compteur) # Counter({3: 2, 2: 2, 1: 1})
C'est particulierement utile pour les modules aux noms longs ou les bibliotheques tierces comme numpy (importe en np) ou pandas (importe en pd).
from module import * — a eviter
from math import * # Importe TOUT le contenu de math
print(sqrt(16)) # 4.0
print(pi) # 3.141592653589793
Evitez from module import * car :
- Cela pollue l'espace de noms avec des dizaines de noms inconnus
- On ne sait plus d'ou vient chaque fonction
- Des conflits de noms silencieux peuvent survenir
- Le code devient difficile a lire et a maintenir
La bibliotheque standard : les modules essentiels
math — operations mathematiques
import math
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
print(math.sqrt(144)) # 12.0
print(math.pow(2, 10)) # 1024.0
print(math.log(100, 10)) # 2.0
print(math.sin(math.pi/2)) # 1.0
print(math.factorial(5)) # 120
print(math.gcd(12, 8)) # 4
random — nombres aleatoires
import random
print(random.random()) # Flottant entre 0.0 et 1.0
print(random.randint(1, 6)) # Entier entre 1 et 6 inclus
print(random.uniform(0.0, 10.0)) # Flottant entre 0.0 et 10.0
nombres = [1, 2, 3, 4, 5]
random.shuffle(nombres) # Melange en place
print(nombres)
print(random.choice(nombres)) # Choisit un element au hasard
print(random.sample(nombres, 3)) # Choisit 3 elements sans repetition
random.seed(42) # Fixe la graine pour des resultats reproductibles
datetime — dates et heures
from datetime import datetime, date, timedelta
# Date et heure actuelles
maintenant = datetime.now()
print(maintenant) # 2024-01-15 10:30:45.123456
print(maintenant.year) # 2024
print(maintenant.strftime('%d/%m/%Y')) # 15/01/2024
# Date uniquement
aujourd_hui = date.today()
print(aujourd_hui) # 2024-01-15
# Durees
dans_une_semaine = aujourd_hui + timedelta(days=7)
print(dans_une_semaine)
# Calcul de difference
naissance = date(1990, 5, 20)
age = (aujourd_hui - naissance).days // 365
print(f"Age : {age} ans")
os — interactions avec le systeme d'exploitation
import os
# Repertoire courant
print(os.getcwd()) # /home/user/projets
# Lister les fichiers
print(os.listdir('.'))
# Verifier l'existence
print(os.path.exists('mon_fichier.txt')) # True ou False
print(os.path.isfile('script.py')) # True si c'est un fichier
print(os.path.isdir('mon_dossier')) # True si c'est un dossier
# Construire des chemins (portable Mac/Linux/Windows)
chemin = os.path.join('dossier', 'sous-dossier', 'fichier.txt')
print(chemin) # dossier/sous-dossier/fichier.txt
# Variables d'environnement
print(os.environ.get('HOME'))
print(os.environ.get('DATABASE_URL', 'sqlite:///default.db'))
sys — parametres et fonctions du systeme
import sys
print(sys.version) # Version de Python
print(sys.platform) # 'linux', 'darwin', 'win32'
print(sys.argv) # Arguments de la ligne de commande
print(sys.path) # Chemins de recherche des modules
# Quitter le programme
# sys.exit(0) # 0 = succes, autre = erreur
re — expressions regulieres
import re
texte = "Mon email est alice@example.com et bob@test.fr"
# Rechercher un motif
match = re.search(r'\w+@\w+\.\w+', texte)
if match:
print(match.group()) # alice@example.com
# Trouver toutes les occurrences
emails = re.findall(r'\w+@\w+\.\w+', texte)
print(emails) # ['alice@example.com', 'bob@test.fr']
# Remplacer
resultat = re.sub(r'\d+', 'X', "Il y a 3 chats et 12 chiens")
print(resultat) # Il y a X chats et X chiens
# Valider un format (numero de telephone)
pattern = r'^\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$'
print(bool(re.match(pattern, '06-12-34-56-78'))) # True
json — serialisation JSON
import json
# Dict Python vers JSON
data = {'nom': 'Alice', 'age': 25, 'langages': ['Python', 'JS']}
json_str = json.dumps(data, indent=2)
print(json_str)
# JSON vers dict Python
texte_json = '{"ville": "Paris", "population": 2161000}'
obj = json.loads(texte_json)
print(obj['ville']) # Paris
# Lire/ecrire un fichier JSON
with open('config.json', 'w') as f:
json.dump(data, f, indent=2)
with open('config.json', 'r') as f:
config = json.load(f)
collections — structures de donnees avancees
from collections import Counter, defaultdict, OrderedDict, deque
# Counter : compter les occurrences
mots = ['chat', 'chien', 'chat', 'oiseau', 'chat', 'chien']
compteur = Counter(mots)
print(compteur) # Counter({'chat': 3, 'chien': 2, 'oiseau': 1})
print(compteur.most_common(2)) # [('chat', 3), ('chien', 2)]
# defaultdict : dict avec valeur par defaut
scores = defaultdict(list)
scores['Alice'].append(90)
scores['Alice'].append(85)
scores['Bob'].append(70)
print(dict(scores)) # {'Alice': [90, 85], 'Bob': [70]}
# deque : file/pile double
file = deque([1, 2, 3])
file.append(4) # Ajoute a droite
file.appendleft(0) # Ajoute a gauche
file.pop() # Retire a droite
file.popleft() # Retire a gauche
print(file) # deque([1, 2, 3])
Creer son propre module
Pour creer un module, il suffit de creer un fichier .py :
# geometrie.py
PI = 3.14159265
def aire_cercle(rayon):
"""Calcule l'aire d'un cercle."""
return PI * rayon ** 2
def aire_rectangle(largeur, hauteur):
"""Calcule l'aire d'un rectangle."""
return largeur * hauteur
def aire_triangle(base, hauteur):
"""Calcule l'aire d'un triangle."""
return 0.5 * base * hauteur
Puis dans un autre fichier du meme dossier :
# main.py
import geometrie
print(geometrie.aire_cercle(5)) # 78.53981625
print(geometrie.aire_rectangle(4, 6)) # 24
from geometrie import aire_triangle
print(aire_triangle(3, 8)) # 12.0
Packages : organiser ses modules
Un package est un dossier contenant un fichier __init__.py et d'autres modules.
mon_projet/
main.py
utilitaires/
__init__.py
calculs.py
formatage.py
validation.py
Le fichier __init__.py (meme vide) indique a Python que ce dossier est un package.
# utilitaires/calculs.py
def additionner(a, b):
return a + b
# main.py
from utilitaires.calculs import additionner
from utilitaires import formatage
print(additionner(3, 5)) # 8
Le garde if __name__ == "__main__":
C'est l'un des motifs les plus importants en Python. Comprendre pourquoi requiert de comprendre la variable __name__.
Quand Python execute un fichier :
- Si c'est le fichier principal lance directement :
__name__vaut"__main__" - Si c'est un module importe par un autre fichier :
__name__vaut le nom du fichier
# utilitaires.py
def calculer_tva(prix):
return prix * 0.20
def demo():
print("Demo TVA:", calculer_tva(100))
# Ce bloc ne s'execute QUE si on lance ce fichier directement
# Il ne s'execute PAS quand ce fichier est importe
if __name__ == "__main__":
demo()
print("Tests passes !")
Sans ce garde, le code de test s'executerait a chaque import du module, ce qui est tres indesirable.
Installer des packages tiers : pip
pip est le gestionnaire de packages de Python. Il permet d'installer des milliers de packages depuis PyPI.
# Installer un package
pip install requests
# Installer une version specifique
pip install requests==2.31.0
# Mettre a jour un package
pip install --upgrade requests
# Desinstaller
pip uninstall requests
# Lister les packages installes
pip list
# Voir les infos d'un package
pip show requests
Environnements virtuels : venv
Un environnement virtuel isole les dependances de chaque projet. Sans venv, tous vos projets partagent les memes packages, ce qui cause des conflits de versions.
# Creer un environnement virtuel
python -m venv venv
# Activer (Linux / macOS)
source venv/bin/activate
# Activer (Windows)
venv\Scripts\activate
# Vous verrez (venv) dans votre terminal
(venv) $ pip install flask
# Desactiver
deactivate
Creez toujours un environnement virtuel pour chaque projet. Ajoutez le dossier venv/ a votre .gitignore — il ne doit jamais etre commite car il est reconstitue depuis requirements.txt.
requirements.txt : les dependances du projet
# Generer le fichier avec les packages installes et leurs versions
pip freeze > requirements.txt
# Contenu typique de requirements.txt :
# flask==3.0.0
# requests==2.31.0
# python-dotenv==1.0.0
# Installer toutes les dependances depuis le fichier
pip install -r requirements.txt
Ce fichier est essentiel pour que vos collegues ou un serveur puissent reconstruire exactement le meme environnement.
Exercices pratiques
Exercice 1 : Importer math et utiliser pi
Placez toujours vos imports en haut du fichier, avant tout autre code. C'est la convention PEP 8 : d'abord les modules de la bibliotheque standard, puis les packages tiers, puis vos propres modules, separes par une ligne vide.
Exercice 2 : Utiliser random.randint()
Pour les tests ou simulations qui doivent donner les memes resultats, utilisez random.seed(42) avant vos appels aleatoires. Cela rend vos resultats reproductibles tout en conservant le comportement aleatoire pour la production.
Exercice 3 : Utiliser datetime.now()
datetime.now() retourne l'heure locale. Pour des applications web ou distribuees, utilisez datetime.utcnow() ou mieux, datetime.now(timezone.utc) avec from datetime import timezone. Stockez toujours vos dates en UTC dans les bases de donnees.
Exercice 4 : Utiliser os.path.exists()
Utilisez toujours os.path.join() pour construire des chemins de fichiers. Cela garantit la compatibilite entre Linux/macOS (separateur /) et Windows (separateur \). Encore mieux : utilisez le module pathlib disponible depuis Python 3.4.
Exercice 5 : Le garde __name__ == "__main__"
Encapsulez toujours le code de lancement dans une fonction main() et appelez-la via le garde if __name__ == "__main__":. Cela rend votre code testable (on peut importer sans effets de bord) et clair (le point d'entree est identifiable immediatement).
Quiz de revision
Une solution
Vous devez être connecté pour voir le contenu.