Pour exécuter un programme python en ligne de commande, il faut surtout choisir la bonne forme de lancement, vérifier l’interpréteur réellement utilisé et éviter les pièges de chemin relatif. Je vais vous montrer la méthode la plus simple pour un fichier isolé, puis la version plus robuste quand le projet contient plusieurs modules, des dépendances ou des arguments. L’idée est de passer d’un test rapide à une exécution fiable, sans bricolage inutile.
Les repères à garder avant de lancer un script Python
-
python script.pyreste la commande la plus directe pour un fichier unique. -
python -m package.moduledevient préférable dès que le code vit dans un projet structuré. - Un environnement virtuel évite de mélanger les dépendances du système et celles du projet.
-
if __name__ == "__main__":garde le script importable et évite les effets de bord au chargement. - La plupart des blocages viennent du PATH, du dossier courant ou d’un venv non activé.
Choisir la bonne commande selon le contexte
La documentation officielle de Python présente python myscript.py comme le cas le plus courant, et c’est logique : quand on veut juste tester un fichier isolé, c’est le chemin le plus court. Mais toutes les commandes ne racontent pas la même histoire : certaines exécutent un fichier, d’autres un module, d’autres encore une seule instruction. Quand on choisit mal, on obtient vite des imports qui cassent, un chemin de travail inattendu ou un comportement différent selon l’OS.
| Commande | Quand je l’utilise | Atout principal | Limite à connaître |
|---|---|---|---|
python script.py |
Script unique, test rapide, prototype | Simple et lisible | Le répertoire courant et le PATH doivent être corrects |
python -m package.module |
Projet structuré, imports internes, package | Résout mieux les imports du projet | Nécessite une vraie structure de module ou de package |
python -c "..." |
Commande ponctuelle, debug express, one-liner | Très rapide pour un test court | Peu lisible dès que la logique grossit |
./script.py |
Exécution directe sous Unix avec shebang | Pratique pour un outil local | Permissions et première ligne d’interpréteur nécessaires |
Je garde une règle simple : fichier unique, lancement direct ; projet structuré, lancement en module ; test ponctuel, commande courte. Sur Windows, le lanceur py reste utile quand plusieurs versions de Python cohabitent, tandis que sur macOS et Linux on voit souvent python3 ou l’environnement virtuel du projet. Une fois ce choix fait, il faut s’assurer que le bon interpréteur répond vraiment dans votre terminal.

Préparer l’environnement et vérifier l’interpréteur
Avant d’exécuter quoi que ce soit, je vérifie toujours trois choses : la version de Python, l’emplacement de l’exécutable et l’existence d’un environnement virtuel. Cette étape paraît banale, mais elle élimine une bonne partie des erreurs qui donnent l’impression que le script est cassé alors que le terminal pointe simplement vers la mauvaise installation.
-
python --versionpour confirmer la version réellement appelée. -
python -c "import sys; print(sys.executable)"pour voir le chemin exact de l’interpréteur. -
python -m venv .venvpour créer un environnement propre au projet.
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python script.py
Sur PowerShell, la séquence change légèrement, mais l’idée reste identique : faire en sorte que le Python du projet soit celui qui exécute le script.
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python script.py
Je préfère cette discipline dès qu’il y a plus d’une dépendance, car elle évite les conflits entre paquets système et paquets locaux. Quand l’environnement est propre, le script doit l’être aussi.
Rendre un script importable sans le casser
Le piège classique consiste à mettre toute la logique au niveau supérieur du fichier. Cela fonctionne au début, puis le projet grossit, on veut importer une fonction ailleurs, et le script se met à exécuter du code au mauvais moment. Je préfère isoler l’exécution dans une fonction main() et garder le point d’entrée explicite.
from pathlib import Path
def main() -> int:
base_dir = Path(__file__).resolve().parent
data_file = base_dir / "data" / "input.txt"
print(f"Lecture de {data_file}")
# Traitement principal ici
return 0
if __name__ == "__main__":
raise SystemExit(main())
Ce schéma fait trois choses utiles à la fois : il laisse le module importable, il rend l’entrée du programme lisible, et il permet de renvoyer un code de sortie propre. Pour moi, c’est le meilleur compromis entre simplicité et robustesse. Une fois cette base en place, la question suivante devient celle des arguments transmis depuis le terminal.
Passer des arguments et récupérer la sortie
Un script de ligne de commande devient vite plus utile quand il accepte des paramètres. Python fournit sys.argv pour les récupérer tels quels, mais dès qu’il y a plus de deux options, argparse devient nettement plus propre. C’est l’outil que je recommande presque systématiquement pour un vrai usage, d’autant qu’il génère aussi l’aide --help automatiquement.
import argparse
parser = argparse.ArgumentParser(description="Traite un fichier texte.")
parser.add_argument("fichier")
parser.add_argument("--seuil", type=float, default=0.8)
args = parser.parse_args()
print(args.fichier, args.seuil)
Avec ce type de structure, l’appel ressemble à ceci : python script.py donnees.txt --seuil 0.9. Le nom du script est toujours présent en position zéro dans sys.argv, puis viennent les arguments du lancement. J’ajoute presque toujours un code de sortie explicite, parce qu’un script qui réussit doit renvoyer 0, et un script en erreur doit renvoyer une valeur non nulle. Ce détail compte beaucoup dès qu’un outil externe, un planificateur ou un pipeline doit interpréter le résultat.
Corriger les erreurs les plus fréquentes
Quand un script refuse de démarrer, le problème n’est pas toujours dans le code. Très souvent, il se cache dans le contexte d’exécution. Je regroupe les cas les plus courants dans un tableau parce qu’ils se diagnostiquent plus vite ainsi que par de longues explications.
| Symptôme | Cause probable | Correction utile |
|---|---|---|
python n’est pas reconnu ou la commande est introuvable |
Python n’est pas dans le PATH ou le mauvais lanceur répond |
Vérifier l’installation, rouvrir le terminal, tester py sur Windows, puis contrôler sys.executable
|
ModuleNotFoundError |
Dépendance absente du bon environnement | Activer le venv et installer avec python -m pip install ...
|
No such file or directory ou fichier introuvable |
Chemin relatif mal évalué | Construire les chemins à partir de __file__ ou du dossier projet |
Permission denied sous Unix |
Fichier non exécutable ou shebang absent | Ajouter #!/usr/bin/env python3 puis lancer chmod +x script.py
|
| Le script fonctionne dans l’IDE mais pas dans le terminal | Dossier courant différent ou environnement implicite de l’éditeur | Lancer depuis la racine du projet et rendre les chemins explicites |
Si le doute persiste, je commence toujours par afficher le dossier courant, le chemin de l’interpréteur et la liste des arguments reçus. Trois commandes suffisent souvent à faire tomber l’ambiguïté. Le terminal ne ment pas, mais il n’explique pas toujours ce qu’il fait à votre place.
La routine que j’applique pour un lancement propre
Quand je veux un script fiable, je ne cherche pas une astuce plus brillante que les autres. Je suis une séquence simple et répétable : bon interpréteur, bon dossier, bons arguments, bon code de sortie. C’est précisément cette régularité qui évite les faux diagnostics.
- Je vérifie la commande réellement exécutée avec
sys.executable. - Je travaille dans un environnement virtuel dès que le projet a des dépendances.
- Je sépare la logique métier de l’entrée terminal dans
main(). - Je construis les chemins de fichiers de manière explicite, jamais par supposition.
- Je documente la commande de lancement dans le projet si elle doit être répétée.