# Modules et paquets Python : import, pip, venv et bibliothèques expliqués simplement

URL: https://skillaria.top/fr/guides/python/modules-paquets-python

Un module en Python est un fichier .py, un paquet est un dossier de modules, et une bibliothèque est un ensemble de paquets ; on les charge avec import. Les bibliothèques tierces s'installent avec pip (ou uv) dans un environnement virtuel venv, un dossier isolé avec son propre interpréteur et ses propres paquets, afin que les versions des différents projets n'entrent pas en conflit.

Un module en Python est un simple fichier de code, et `import` est le moyen d'en utiliser les fonctions et les classes. Les modules se regroupent en paquets, les paquets en bibliothèques ; et pour que les bibliothèques tierces de différents projets ne se gênent pas, on les installe dans un environnement virtuel venv. Voyons toute la chaîne : ce que fait `import`, comment est organisé un paquet, comment fonctionnent pip et venv, et quels sont les imports paresseux apparus dans Python 3.15.

## Module, paquet, bibliothèque : quelles différences

| Notion | Ce que c'est | Exemple |
| --- | --- | --- |

| Module | Un fichier `.py` ; le nom du module est le nom du fichier sans extension | `categories.py` → `import categories` |

| Paquet | Un dossier contenant des modules et un fichier `__init__.py` | `depenses/rapport.py` → `from depenses.rapport import construire` |

| Bibliothèque | Un ensemble prêt à l'emploi de modules et de paquets pour une tâche donnée | `requests`, `pandas`, la bibliothèque standard `pathlib` |

| Distribution (paquet PyPI) | Une archive installée par pip | `pip install requests` |

Dans la conversation, on mélange souvent « bibliothèque », « paquet » et « module ». C'est normal. Ce qu'il faut retenir : techniquement, `import` charge toujours un module ou un paquet, et pip installe une distribution depuis PyPI, qui contient des paquets.

## Comment fonctionne import en Python

Il existe plusieurs formes d'import, et on les rencontre toutes dans du code réel :

```
import math                    # module entier, appel via math.sqrt
from math import sqrt, pi      # noms isolés
import datetime as dt          # alias
from collections import Counter as C

print(math.sqrt(16), sqrt(9), pi)
print(dt.date.today())
```

Les alias sont d'usage courant pour les grandes bibliothèques : `import numpy as np`, `import pandas as pd`. La forme `from module import *` est à éviter : elle encombre l'espace de noms et masque l'origine des noms.

### Ce que fait réellement import

1. Il cherche le module dans le cache `sys.modules`. S'il est déjà chargé, il le renvoie simplement.
2. Sinon, il cherche le fichier dans les dossiers listés dans `sys.path` : dossier du script lancé, bibliothèque standard, site-packages de l'environnement.
3. Il exécute le fichier trouvé en entier, de haut en bas.
4. Il place l'objet module dans le cache et le lie au nom.

On en tire deux conséquences pratiques. Un second `import` du même module est presque gratuit : le code ne s'exécute pas une seconde fois. En revanche, tout le code de premier niveau d'un module, y compris les `print` et les calculs lourds, s'exécute dès l'import.

```
import sys
for p in sys.path:
    print(p)
print("math" in sys.modules)
```

### if __name__ == "__main__"

Puisque l'import exécute le fichier, il faut un moyen de distinguer « on m'a lancé comme script » de « on m'a importé ». C'est le rôle de la variable `__name__` : lors du lancement du fichier, elle vaut `"__main__"`, lors de l'import, elle vaut le nom du module.

```
# categories.py
def deviner(titre: str) -> str:
    return "alimentation" if "café" in titre.lower() else "divers"

if __name__ == "__main__":
    print(deviner("Café du coin"))   # s'exécute seulement avec python categories.py
```

Pour un paquet, on peut aussi placer un fichier `__main__.py` à l'intérieur et le lancer avec `python -m depenses`.

## Modules standard de Python

Python est livré « avec piles incluses » : des centaines de modules intégrés sont disponibles sans installation. Les plus utilisés :

| Module | À quoi il sert |
| --- | --- |

| `os`, `sys`, `pathlib`, `shutil` | Système, chemins, fichiers |

| `json`, `csv`, `pickle` | Formats de données |

| `datetime`, `time`, `calendar` | Dates et heures |

| `math`, `random`, `statistics`, `fractions` | Nombres |

| `re`, `string` | Traitement du texte |

| `collections`, `itertools`, `functools` | Structures de données et itérateurs |

| `logging`, `argparse`, `subprocess` | Journaux, arguments de ligne de commande, lancement de programmes |

| `asyncio`, `threading` | Asynchronisme et threads |

La liste complète des modules de la bibliothèque standard est disponible dans `sys.stdlib_module_names` (Python 3.10 et plus). Pour voir ce que contient un module, utilisez `dir(math)` et `help(math)`.

## Son propre paquet : structure d'un projet

Quand les modules deviennent nombreux, on les regroupe en paquet. Une organisation courante est le « src-layout » :

```
depenses-projet/
├── pyproject.toml
└── src/
    └── depenses/
        ├── __init__.py
        ├── cli.py
        ├── analyse.py
        ├── categories.py
        └── rapport.py
```

À l'intérieur d'un paquet, les modules s'importent entre eux via le nom du paquet (`from depenses.categories import deviner`) ou de façon relative (`from .categories import deviner`). L'import relatif ne fonctionne qu'à l'intérieur du paquet, et non dans un fichier lancé directement comme script.

## pip en Python : installer des bibliothèques

Les bibliothèques tierces se trouvent dans le catalogue PyPI, et on les installe avec pip, livré avec Python. Le plus sûr est d'appeler pip via l'interpréteur : la bibliothèque arrive ainsi dans le Python avec lequel vous lancez votre code.

```
python -m pip install requests          # installer
python -m pip install "pandas>=2.3"     # avec une contrainte de version
python -m pip install --upgrade requests
python -m pip uninstall requests        # désinstaller
python -m pip list                      # liste des paquets installés
python -m pip show requests             # version et dépendances
python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt
```

Sous Windows, on utilise souvent le lanceur `py` à la place de `python`. Si pip est absent, le module intégré l'installe : `python -m ensurepip --upgrade`.

### Bibliothèques Python populaires

PyPI compte des centaines de milliers de paquets, mais la plupart des projets utilisent toujours la même petite liste. Commencez par elle plutôt que de chercher l'exotique.

| Tâche | Bibliothèques |
| --- | --- |

| Requêtes HTTP et API | `requests`, `httpx` |

| Analyse de données et tableaux | `pandas`, `numpy` |

| Graphiques | `matplotlib` |

| Services web | `fastapi`, `django`, `flask` |

| Tests | `pytest` |

| Images | `pillow` (importée sous le nom `PIL`) |

Attention : le nom d'installation et le nom d'import ne coïncident pas toujours. On installe `pip install pillow`, mais on écrit `from PIL import Image` ; on installe `opencv-python`, mais on importe `cv2`. Si `import` échoue juste après une installation, vérifiez dans la documentation du paquet le nom sous lequel il s'importe.

### Installer des bibliothèques sous Linux

Sur les versions récentes de Debian et Ubuntu, `pip install` dans le Python du système se termine par l'erreur `externally-managed-environment` (PEP 668). C'est une protection : le Python du système appartient au gestionnaire de paquets de l'OS, et pip ne doit pas le casser. La bonne solution n'est pas `--break-system-packages`, mais un environnement virtuel.

## venv en Python : l'environnement virtuel

Un environnement virtuel est un dossier distinct, avec sa propre copie de l'interpréteur (un lien vers lui) et son propre site-packages. Les bibliothèques qui y sont installées ne sont visibles que pour ce projet. Un projet peut donc utiliser Django 4 et un autre Django 5 sans conflit.

Le module `venv` est intégré à Python, il n'y a rien à installer à part (sous Debian et Ubuntu, il faut parfois le paquet système `python3-venv`).

```
# créer l'environnement dans le dossier .venv
python -m venv .venv

# activer : Linux et macOS
source .venv/bin/activate
# activer : Windows PowerShell
.venv\Scripts\Activate.ps1

# désormais pip installe les paquets dans .venv
python -m pip install requests
python -c "import sys; print(sys.prefix)"

# quitter l'environnement
deactivate
```

Après l'activation, le préfixe `(.venv)` apparaît au début de la ligne du terminal. Le dossier de l'environnement ne se met pas dans git (ajoutez `.venv/` au `.gitignore`) et ne se transporte pas d'une machine à l'autre : on fige la liste des dépendances et on recrée l'environnement. Si PowerShell refuse d'exécuter le script d'activation, autorisez-le pour l'utilisateur : `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`.

### uv et pyproject.toml

Les projets modernes décrivent leurs dépendances dans `pyproject.toml`. Le gestionnaire uv, utilisé dans le cours, regroupe la création de l'environnement et l'installation : `uv add pandas` télécharge le paquet, l'inscrit dans `pyproject.toml` et fige les versions exactes dans `uv.lock`. Un collègue qui clone le projet lance `uv sync` et obtient exactement le même environnement.

```
[project]
name = "depenses"
version = "0.1.0"
requires-python = ">=3.15"
dependencies = [
    "pandas>=2.3",
]

[project.scripts]
depenses = "depenses.cli:main"
```

## Imports paresseux dans Python 3.15 (PEP 810)

La nouveauté principale de la version 3.15 sur ce sujet est le mot-clé `lazy`. Les bibliothèques lourdes se chargent lentement : dans la mesure faite pour le cours sur l'image `python:3.15-slim`, un `import pandas` ordinaire prend environ 415 ms, contre environ 13 ms pour `lazy import pandas`. Pour un utilitaire en ligne de commande qu'on lance juste pour afficher `--help`, la différence est énorme.

```
lazy import pandas as pd
lazy from depenses.rapport import construire_rapport

def main() -> None:
    ...
    df = pd.read_csv(chemin)   # le chargement réel de pandas a lieu ici
```

Au lieu du module, le nom reçoit un objet-proxy (`types.LazyImportType`), et l'import réel n'a lieu qu'au premier accès au nom. Si l'on n'en a jamais besoin, aucun temps n'est dépensé.

### Limites des imports paresseux

- Autorisés seulement au niveau supérieur du module : à l'intérieur d'une fonction, d'une classe ou d'un `try/except`, c'est une `SyntaxError`.
- `lazy from x import *` est interdit.
- `ModuleNotFoundError` apparaît non pas au démarrage, mais au premier usage.

## FAQ

**Faut-il créer un venv pour chaque projet ?**

Oui, c'est une bonne pratique : chaque projet a ses propres versions de bibliothèques, et un environnement séparé évite les conflits sans encombrer le Python du système.

**Quelle est la différence entre pip et uv ?**

pip se contente d'installer des paquets, tandis que uv crée aussi l'environnement, inscrit les dépendances dans pyproject.toml et fige les versions exactes dans un fichier de verrouillage ; il est en outre nettement plus rapide.

**Comment voir la liste des bibliothèques Python installées ?**

Exécutez python -m pip list dans l'environnement voulu ; pip freeze affiche la même liste au format requirements.txt.

**Où sont stockés les modules installés ?**

Dans le dossier site-packages de l'environnement actif ; le chemin d'un module se lit dans son attribut __file__, par exemple import requests; print(requests.__file__).

**Peut-on copier le dossier venv sur un autre ordinateur ?**

Non : l'environnement est lié aux chemins et à l'interpréteur de la machine. On transporte la liste des dépendances et on recrée l'environnement sur place.


---
Source: Skillaria.Top (https://skillaria.top)
