Chapitre 199 minDébutant
Aide-mémoire Python
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- retrouver vite la syntaxe et les méthodes courantes ;
- choisir le bon module de la bibliothèque standard ;
- éviter les pièges les plus fréquents.
Cet aide-mémoire Python rassemble sur une page les commandes pour installer et lancer Python, la syntaxe de base, les méthodes des chaînes, listes et dictionnaires, la lecture des fichiers CSV et JSON, les modules de la bibliothèque standard utiles à l'administration, les expressions régulières, pytest et les pièges les plus fréquents. Chaque notion est détaillée dans son chapitre.
Installer, lancer, gérer les paquets
| Besoin | Windows | Linux et macOS |
|---|---|---|
| Installer Python | Gestionnaire d'installation, puis py install 3.15 | sudo apt install python3 python3-venv python3-pip (Debian) |
| Version | python --version, py list | python3 --version |
| Lancer un script | python script.py, py -V:3.14 script.py | python3 script.py, ou ./script.py avec un shebang |
| Créer un environnement | python -m venv .venv | python3 -m venv .venv |
| L'activer | .venv\Scripts\Activate.ps1 | source .venv/bin/activate |
| Installer un paquet | python -m pip install requests | idem, environnement activé |
| Figer, réinstaller | python -m pip freeze > requirements.txt, python -m pip install -r requirements.txt | idem |
| Avec uv | uv init --no-package projet, uv add requests, uv run main.py, uv sync, uv run script.py (en-tête PEP 723) | idem |
Syntaxe de base
nom = "srv-ad"; taux = 87.5; actif = True; rien = None # str, float, bool, NoneType
7 / 2 # 3.5 7 // 2 # 3 7 % 2 # 1 2 ** 10 # 1024
f"{nom:<14}{taux:6.1f} % {taux=}" # f-string et formats
int("42"), float("3.5"), str(42), round(3.14159, 2) # conversions
if taux >= 90:
niveau = "CRITIQUE"
elif taux >= 80:
niveau = "ALERTE"
else:
niveau = "OK"
match code:
case 200 | 201: sens = "succès"
case _: sens = "autre"
for i in range(1, 11, 3): ... # 1, 4, 7, 10
for rang, x in enumerate(liste, start=1): ...
for a, b in zip(liste1, liste2): ...
while condition: ... # break : sortir ; continue : tour suivant
def niveau(taux: float, alerte: float = 80) -> str:
"""Docstring : ce que fait la fonction."""
return "ALERTE" if taux >= alerte else "OK"
if __name__ == "__main__": # seulement quand le fichier est lancé
main()
Chaînes, listes, tuples, dictionnaires, ensembles
| Structure | Opérations courantes |
|---|---|
Chaîne s | s[i], s[-1], s[a:b], len(s), s.strip(), s.split(";"), ";".join(liste), s.lower(), s.replace(a, b), s.startswith(x), x in s |
Liste l | l.append(x), l.insert(i, x), l.remove(x), l.pop(), l.sort(), sorted(l, key=…, reverse=True), l.copy(), sum(l), min(l), max(l) |
Tuple t | t[i], a, b, c = t, premier, *reste = t ; non modifiable |
Dictionnaire d | d[c], d.get(c, defaut), d[c] = v, del d[c], c in d, d.items(), d.keys(), d.values(), d.setdefault(c, []) |
Ensemble e | e.add(x), x in e, a & b, a | b, a - b, a ^ b, set() pour l'ensemble vide |
| Comptage, regroupement | Counter(liste).most_common(3), defaultdict(list) |
| Compréhensions | [f(x) for x in l if cond], {k: v for k, v in d.items()}, {x for x in l}, sum(1 for x in l if cond) |
Fichiers texte, CSV et JSON
from pathlib import Path
import csv, json
p = Path("rapports") / "controle.txt"
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("texte\n", encoding="utf-8")
with open(p, "a", encoding="utf-8") as f: # "r" lire, "w" écraser, "a" ajouter
f.write("ligne\n")
for fichier in sorted(Path("journaux").rglob("*.log")): ...
with open("inventaire.csv", encoding="utf-8-sig", newline="") as f: # utf-8-sig : BOM d'Excel
lignes = list(csv.DictReader(f, delimiter=";")) # liste de dictionnaires
with open("sortie.csv", "w", encoding="utf-8-sig", newline="") as f:
w = csv.DictWriter(f, fieldnames=["nom", "ip"], delimiter=";")
w.writeheader(); w.writerows(lignes_a_ecrire)
donnees = json.loads(Path("config.json").read_text(encoding="utf-8"))
texte = json.dumps(donnees, indent=2, ensure_ascii=False)
Exceptions et code de retour
try:
valeur = int(saisie)
except ValueError as erreur: # seulement ce qu'on sait traiter
print("Pas un nombre :", erreur)
else:
print("OK") # si aucune exception
finally:
print("toujours exécuté")
raise ValueError(f"seuil invalide : {seuil}")
sys.exit(1) # 0 = succès ; message d'erreur : print(..., file=sys.stderr)
Un traceback se lit de bas en haut : le type et le message, la ligne fautive, puis le chemin des appels.
Bibliothèque standard pour l'administration
| Module | Pour | À retenir |
|---|---|---|
os | Variables d'environnement | os.environ.get("VAR", "défaut"), os.environ["SECRET"] |
shutil | Copier, déplacer, archiver, espace disque | copy2, copytree, move, make_archive, disk_usage, which |
subprocess | Lancer une commande | subprocess.run([cmd, arg], capture_output=True, text=True, timeout=10) ; jamais shell=True avec une saisie |
argparse | Options de la ligne de commande | add_argument("source"), add_argument("-n", "--simulation", action="store_true"), type=int |
logging | Journal | basicConfig(level=…, format=…, handlers=[…]), journal.info("… %s", x), journal.exception() |
datetime | Dates et durées | datetime.now(), date.fromisoformat(), strftime("%Y-%m-%d_%H%M"), strptime, timedelta(days=30) |
re | Expressions régulières | re.search, re.fullmatch, re.findall, re.sub, re.compile, groupes (?P<nom>…) |
ipaddress | Adresses et réseaux | ip_network("192.168.10.176/28"), .hosts(), ip in reseau, .overlaps(), .subnets(new_prefix=26) |
socket | Port TCP, DNS | socket.create_connection((hote, port), timeout=2), socket.gethostbyname(nom) |
hashlib | Empreintes | hashlib.file_digest(f, "sha256").hexdigest() (fichier ouvert en "rb") |
zipfile | Archives zip | ZipFile(nom, "w", compression=ZIP_DEFLATED), .write(f, arcname=…), .testzip() |
csv, json | Échanges de données | Voir ci-dessus |
sqlite3 | Base SQL locale | connexion.execute("… WHERE code = ?", (code,)), with connexion: pour une transaction |
urllib.request | HTTP sans paquet | urlopen(Request(url, headers=…), timeout=10) |
concurrent.futures | Paralléliser des attentes | ThreadPoolExecutor(max_workers=32).map(fonction, elements) |
collections | Compter, regrouper | Counter, defaultdict |
dataclasses, enum | Classes de données | @dataclass(order=True), field(default_factory=list), StrEnum |
Expressions régulières
| Motif | Sens |
|---|---|
\d \w \s . | Chiffre, caractère de mot, espace, n'importe quel caractère |
[a-z] [^;] | Un caractère de l'intervalle ; tout sauf ; |
* + ? {n} {m,n} | 0 ou plus, 1 ou plus, 0 ou 1, exactement n, de m à n |
^ $ \b | Début, fin, frontière de mot |
(…) (?P<nom>…) (?:…) a|b | Groupe, groupe nommé, groupe sans capture, alternative |
Toujours une chaîne brute : r"\d+". Pour valider une saisie entière : re.fullmatch.
Requêtes HTTP avec requests
r = requests.get(url, params={"page": 1}, headers={"Authorization": f"Bearer {jeton}"}, timeout=5)
r.raise_for_status() # exception si 4xx ou 5xx
donnees = r.json()
r = requests.post(url, json={"mois": "2026-11"}, timeout=5) # corps JSON
# Erreurs : requests.HTTPError, ConnectionError, Timeout ; toutes : requests.RequestException
Tests avec pytest
import pytest
@pytest.mark.parametrize("prefixe, attendu", [(24, 254), (30, 2)])
def test_hotes(prefixe, attendu):
assert hotes(prefixe) == attendu
def test_erreur():
with pytest.raises(ValueError, match="invalide"):
hotes(33)
def test_fichier(tmp_path, monkeypatch): ... # dossier temporaire ; remplacer une fonction
python -m pytest -q lance tout ; -v détaille, -k mot filtre, -x s'arrête au premier échec.
Les pièges les plus fréquents
| Piège | Correction |
|---|---|
input() renvoie une chaîne : "12" + "3" vaut "123" | int(input(...)) |
range(1, 10) s'arrête à 9 | La borne de fin est exclue |
= au lieu de == dans une condition | = affecte, == compare |
liste = liste.sort() donne None | liste.sort() ou liste = sorted(liste) |
b = a ne copie pas une liste | b = a.copy() |
[[0] * 3] * 3 : trois fois la même ligne | [[0] * 3 for _ in range(3)] |
def f(x, l=[]) : liste partagée entre les appels | def f(x, l=None), puis if l is None: l = [] |
0.1 + 0.2 == 0.3 vaut False | round(…, 2), ou math.isclose(a, b) |
"srv-ad\n" == "srv-ad" vaut False | ligne.strip() |
Colonne '\ufeffnom' introuvable dans un CSV | encoding="utf-8-sig" |
except: pass | Intercepter une exception précise, journaliser |
requests.get(url) sans délai | timeout=5 |
| Requête SQL construite avec une f-string | Paramètres ? (ou %s) |
Script nommé csv.py, random.py | Renommer, supprimer __pycache__ |
pip install refusé sur Debian (externally-managed-environment) | Environnement virtuel, ou paquet python3-… |