Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🐍 Python – Le Guide Ultime

Deep Dive (Détaillé) : Syntaxe, POO (Class), Pythonic (Comprehensions), Venv & Écosystème (Web, Data, AI).

1.1 Facile

1. Philosophie & Syntaxe

"Zen of Python". Typage dynamique fort. L'Indentation (pas de {...}).

Zen Indentation
1.2 Facile

2. Types de Base & Slicing

str (.split, .join, f-string), int, bool, None. Slicing ([1:5:2]).

f-string Slicing
1.3 Moyen

3. Structures (List, Dict, Set)

list (mutable), tuple (immutable), dict (clé/valeur), set (uniques). defaultdict.

List Dict
1.4 Moyen

4. Fonctions & Contrôle

def, if/elif/else, lambda, *args, **kwargs, try/except. Type Hinting.

def **kwargs try/except
1.5 Avancé

5. 🚀 Le Style "Pythonic"

Comprehensions, Generators (yield), Context Managers (with open).

Pythonic Comprehensions
2.1 Moyen

6. POO (Classes & Héritage)

class, self, __init__. Héritage (super()). Méthodes Magiques (__str__).

class OOP self
2.2 Avancé

7. POO Avancé (Addons)

Décorateurs (@decorator), Properties (@property), Dataclasses (@dataclass).

@decorator @property
2.3 Moyen

8. Historique des Versions

Évolution sur 10 ans. 3.7 (data classes), 3.8 (walrus), 3.10 (match/case).

Versions match/case
3.1 Facile

9. Modules, Pip & Venv

import, pip, requirements.txt, __init__.py, venv (isolation).

pip venv
3.2 Avancé

10. Frameworks Web

Django (MVT), Flask (Micro), FastAPI (Moderne/Async). Celery (Tâches).

Django FastAPI Celery
3.3 Avancé

11. Frameworks Data & AI

Pandas (DataFrame), NumPy (Arrays), PyTorch/TensorFlow (AI).

Pandas NumPy PyTorch
3.4 Avancé

12. Outils, Plugins & Liens

Ruff, Black (Formatters), Pytest (Tests), Poetry. Plugins (Requests, Pandas).

Ruff Black Pytest
1.1 Philosophie, Syntaxe & Indentation

Python est un langage interprété (pas compilé au sens C++/Java), haut niveau, et multi-plateforme. Il est célèbre pour sa syntaxe claire, lisible (presque de l'anglais) et sa philosophie "Batteries Included" (une bibliothèque standard très riche).

Caractéristiques Clés
  • Typage Dynamique Fort :
    - Dynamique : Pas besoin de déclarer le type (x = 5, puis x = "hello" est OK). Le type est vérifié au moment de l'exécution (runtime).
    - Fort : Interdit les opérations "magiques" (5 + "hello" -> lève une TypeError, contrairement à JavaScript qui concaténerait en "5hello").
  • Interprété : Le code est lu ligne par ligne par un interpréteur (le plus courant : CPython).
  • Lisibilité (Indentation) : Utilise l'indentation (le "whitespace", 4 espaces par convention) pour définir les blocs de code (au lieu de {...}), forçant un code propre.
Le "Zen of Python" (import this)

La philosophie de Python, écrite par Tim Peters. Tapez import this dans un interpréteur Python :

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Readability counts.
...
Syntaxe de Base
# Convention: utiliser le snake_case
user_name = "Alice"
user_age = 30
is_admin = True # Note: True/False (Majuscule)
rien = None     # Le "Nul" de Python

# f-strings (formatage moderne)
print(f"User {user_name} a {user_age} ans.")

# L'Indentation (pas de '{...}')
if user_age > 18:
    print("Majeur")
else:
    print("Mineur")
1.2 Types de Base (str, int) & Slicing
Types Scalaires (Simples)
  • str : String (Chaîne). ("Hello" ou 'Hello').
  • int : Entier (123, -42).
  • float : Flottant (3.14159).
  • bool : Booléen (True, False).
  • None : Le "Nul" de Python (None).
Strings (str) - Méthodes & f-strings
# f-strings (Le "must-know")
nom = "Alice"
age = 30
print(f"Bonjour {nom}, vous avez {age} ans.")
print(f"Calcul: { (age * 2) / 3 :.2f }") # f"Pi vaut: 3.14"

# Méthodes courantes
ligne = "  Bonjour, ceci est un test.  "
print(ligne.strip()) # "Bonjour, ceci est un test." (Enlève whitespace)
print(ligne.split(',')) # ["  Bonjour", " ceci est un test.  "]
print(ligne.startswith("Bonjour")) # False (à cause de l'espace)
print(ligne.strip().startswith("Bonjour")) # True

# Joindre une liste de strings
mots = ["Python", "est", "génial"]
phrase = " ".join(mots) # "Python est génial"
Slicing (Découpage)

Syntaxe [start:stop:step] (stop est *exclu*). Fonctionne sur les listes, tuples, et strings.

items = [0, 10, 20, 30, 40, 50, 60]

# De l'index 1 (inclus) à 4 (exclu)
print(items[1:4]) # [10, 20, 30]

# Du début à l'index 3 (exclu)
print(items[:3]) # [0, 10, 20]

# De l'index 3 (inclus) à la fin
print(items[3:]) # [30, 40, 50, 60]

# Du début à la fin, un item sur 2 (step)
print(items[::2]) # [0, 20, 40, 60]

# Inverser une liste/string
print(items[::-1]) # [60, 50, 40, 30, 20, 10, 0]
1.3 Structures de Données (List, Dict, Set)
List (list) - Mutable

Collection ordonnée et **mutable** (modifiable).

ma_liste = [10, "hello"]
ma_liste.append(True) # [10, "hello", True]
ma_liste.pop(0) # Retire index 0 -> ["hello", True]
print(ma_liste[0]) # "hello"
ma_liste[0] = "world" # ["world", True]
Tuple (tuple) - Immutable

Collection ordonnée et **immutable** (non-modifiable).

mon_tuple = (10, "hello")
# mon_tuple[0] = 99 # ERREUR!

# Unpacking (très courant)
x, y = mon_tuple # (x=10, y="hello")
Dictionnaire (dict) - Clé/Valeur

La structure de données la plus importante. (Map/HashMap).

user = {"name": "Alice", "age": 30}
print(user["name"]) # "Alice"
print(user.get("job", "N/A")) # "N/A" (défaut)
user["age"] = 31

# Itération
for key, value in user.items():
    print(f"{key} -> {value}")
Set (set) - Uniques

Collection non-ordonnée d'éléments **uniques**.

ma_liste = [1, 2, 2, 3, 1]
mon_set = set(ma_liste) # {1, 2, 3}
print(2 in mon_set) # True (très rapide)

set_a = {1, 2, 3}
set_b = {3, 4, 5}
print(set_a | set_b) # Union: {1, 2, 3, 4, 5}
print(set_a & set_b) # Intersection: {3}
Addon (Stdlib) : collections
  • defaultdict : Un dict qui ne lève jamais de KeyError.
    compteur = defaultdict(int) -> compteur["mot"] += 1 (marche même si "mot" n'existe pas, il vaut 0).
  • namedtuple : Un tuple où l'on peut accéder aux champs par un nom.
    Point = namedtuple("Point", ["x", "y"]) -> p = Point(10, 20) -> print(p.x) (affiche 10).
1.4 Fonctions, Contrôle & Erreurs
if / elif / else
age = 25
if age < 18:
    print("Mineur")
elif age >= 65:
    print("Senior")
else:
    print("Majeur")
Boucle for (La boucle "foreach")
# Itérer sur une liste
fruits = ["pomme", "banane", "cerise"]
for fruit in fruits:
    print(fruit)

# Pour obtenir l'index ET la valeur
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")
Boucle while & break/continue
count = 0
while True:
    count += 1
    if count % 2 == 0:
        continue # Saute les chiffres pairs
    print(count)
    if count >= 7:
        break # Arrête la boucle
# (Affiche: 1, 3, 5, 7)
Fonctions (def, lambda, *args, **kwargs)
# 1. Fonction de base avec Type Hinting (Python 3+)
def saluer(nom: str, age: int = 30) -> str:
    # (age=30 est un argument par défaut)
    return f"Bonjour {nom}, tu as {age} ans."

# 2. Fonction "collectrice"
# *args: "avale" tous les arguments positionnels dans un tuple
# **kwargs: "avale" tous les arguments nommés dans un dict
def super_fonction(arg1, *args, **kwargs):
    print(f"Arg1: {arg1}")
    print(f"Autres args: {args}") # (ex: (10, 20))
    print(f"Autres kwargs: {kwargs}") # (ex: {'ville': 'Paris'})

super_fonction("test", 10, 20, ville="Paris", job="Dev")

# 3. Fonction Anonyme (lambda)
# (Utile pour le tri, map, filter)
ma_liste = [{"nom": "Alice", "age": 30}, {"nom": "Bob", "age": 20}]
ma_liste.sort(key=lambda item: item["age"])
Attraper (try/except)
mon_dict = {"cle": "valeur"}
try:
    x = mon_dict["cle_absente"] # Lève une KeyError
except KeyError as e:
    print(f"Erreur attrapée: La clé n'existe pas ! ({e})")
    x = None
except Exception as e:
    print(f"Erreur inconnue: {e}")
else:
    print("Accès au dict réussi.")
finally:
    print("Fin du bloc try (s'exécute toujours).")
Lever (raise)
def set_age(age):
    if not isinstance(age, int):
        raise TypeError(f"L'âge doit être un entier, reçu: {type(age)}")
    if age < 0:
        raise ValueError("L'âge ne peut pas être négatif.")
    
try:
    set_age("vingt")
except (TypeError, ValueError) as e:
    print(e) # "L'âge doit être un entier, reçu: <class 'str'>"
1.5 🚀 Le Style "Pythonic" (Comprehensions & Generators)

Le code "Pythonic" est une façon d'écrire du code qui est "idiomatique", lisible, et qui utilise les forces du langage. La "List Comprehension" en est l'exemple parfait. C'est une façon de créer une liste en une seule ligne lisible.

1. List Comprehension [ ... ]

Objectif : Créer une liste des carrés des 10 premiers chiffres pairs.

Méthode "Classique" (Loop)
carres_pairs = []
for i in range(10):
    if i % 2 == 0:
        carres_pairs.append(i * i)
Méthode "Pythonic" (Comprehension)
carres_pairs = [i * i for i in range(10) if i % 2 == 0]

# Syntaxe: 
# [ (ce que je veux) for (item) in (iterable) if (condition) ]
2. Dict & Set Comprehensions { ... }
# Dict Comprehension
# {clé: valeur for ...}
carres_dict = {i: i * i for i in range(5)}
# Résultat: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# Set Comprehension
ma_liste = [1, 2, 2, 3, 1]
mon_set = {x for x in ma_liste}
# Résultat: {1, 2, 3}
3. Generator Expression ( ... ) & yield

Si la liste est immense (ex: 1 milliard), une "list comprehension" va saturer la RAM. On utilise une "Generator Expression" (avec (...)). Elle ne calcule les valeurs qu'à la demande (lazy).

# Ceci ne calcule RIEN, c'est un "générateur"
carres_gen = (i * i for i in range(1000000000))

# 'yield' est la façon de créer un générateur dans une fonction
def gen_carres(n):
    for i in range(n):
        yield i * i # "Pause" et renvoie la valeur

# Le calcul se fait ici, un par un
for c in carres_gen:
    print(c)
    if c > 100:
        break # Ne calcule pas les 999 millions restants
4. Context Manager (with open)

Ne *jamais* gérer des fichiers manuellement (f.open(), f.close()). La "bonne" façon est d'utiliser with, qui gère le finally (fermeture) pour vous.

# La façon "Pythonic" de gérer les ressources
with open("mon_fichier.txt", "r") as f:
    contenu = f.read()
# (Ici, 'f' est automatiquement fermé, même si une erreur a eu lieu)
2.1 POO (Classes, Héritage, Dunders)

Python est un langage orienté objet (POO). Tout est objet (même les fonctions).

Classe, __init__, et self

self est l'équivalent du this (en Java/JS). C'est le premier argument de *chaque* méthode d'instance. __init__ est le constructeur.

# 1. Définition de la classe
class Utilisateur:
    
    # 2. Constructeur (lancé à la création)
    def __init__(self, nom, email):
        # 3. 'self' fait référence à l'instance
        self.nom = nom
        self.email = email
        self.est_actif = True

    # 4. Méthode d'instance
    def saluer(self):
        return f"Bonjour, je suis {self.nom}."

# 5. Instanciation
user_1 = Utilisateur("Alice", "alice@mail.com")
print(user_1.nom) # "Alice"
Héritage & super()
# 1. La classe "Enfant" hérite de "Utilisateur"
class Admin(Utilisateur):
    
    def __init__(self, nom, email, permissions):
        # 2. On appelle le constructeur parent (Utilisateur)
        super().__init__(nom, email)
        self.permissions = permissions
        
    # 3. On "override" (surcharge) la méthode parent
    def saluer(self):
        return f"[ADMIN] Bonjour, je suis {self.nom}."
Méthodes Magiques (Dunder)

Méthodes spéciales (__nom__) qui définissent le comportement de l'objet.

class Livre:
    def __init__(self, titre, auteur):
        self.titre = titre
        self.auteur = auteur
        
    # 'str(livre)' ou 'print(livre)'
    def __str__(self):
        return f"'{self.titre}' par {self.auteur}"
        
    # 'repr(livre)' (Pour le débug)
    def __repr__(self):
        return f"Livre(titre='{self.titre}')"
        
    # 'len(livre)'
    def __len__(self):
        return len(self.titre)
        
livre = Livre("Dune", "F. Herbert")
print(livre) # "'Dune' par F. Herbert"
2.2 POO Avancé (Décorateurs & Dataclasses)

Les "décorateurs" (@) sont des "addons" pour les fonctions. Ce sont des fonctions qui "enveloppent" d'autres fonctions pour modifier leur comportement.

@staticmethod vs @classmethod
Décorateur1er ArgumentDescription
Méthode d'instance (défaut)selfA accès à l'instance (self.nom).
@classmethodclsA accès à la *Classe* (cls.objects.all()). N'a pas accès à l'instance (self).
@staticmethod(Aucun)N'a accès *ni* à l'instance (self) *ni* à la classe (cls). C'est juste une fonction utilitaire rangée dans la classe.
@property (Getters & Setters "Pythonic")

La "mauvaise" façon (style Java) est user.get_email(). La façon "Pythonic" est d'utiliser @property pour qu'une méthode se comporte comme un attribut.

class Utilisateur:
    def __init__(self, prenom, nom):
        self._email = f"{prenom}.{nom}@mail.com"

    @property
    def email(self):
        return self._email # Getter

    @email.setter
    def email(self, nouvelle_valeur):
        self._email = nouvelle_valeur # Setter
@dataclass (Python 3.7+)

Écrire __init__ et __repr__ est répétitif. Ce décorateur le fait pour vous.

Avant (Classique)
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __repr__(self):
        return f"Point(x={self.x}, y={self.y})"
Après (Dataclass)
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int
2.3 Historique des Versions (10 dernières années)

Python a une cadence de sortie annuelle (en octobre). Les versions "modernes" (post 3.5) ont ajouté des fonctionnalités majeures. La transition Python 2 -> 3 (2008) a été un événement majeur, mais Python 2 est mort et n'est plus supporté depuis 2020.

VersionDate SortieNouveautés Clés
3.5Sep 2015async / await (AsyncIO), Opérateur "unpacking" ** dans les dicts.
3.6Dec 2016f-Strings (formatage littéral), Dictionnaires ordonnés (par défaut).
3.7Juin 2018@dataclasses (POO simplifiée), async/await deviennent mots-clés.
3.8Oct 2019"Walrus Operator" (:=) (assignation dans une expression).
3.9Oct 2020Union de dict (|), str.removeprefix(), Type Hinting natif (list[int]).
3.10Oct 2021match / case (Structural Pattern Matching), ExceptionGroup.
3.11Oct 2022"Faster CPython" (Performances +10-60%), tomllib (pour .toml).
3.12Oct 2023Messages d'erreur améliorés, support de type (Type Hinting).
3.13Oct 2024Améliorations du JIT (expérimental), Loop de asyncio ré-écrit en C.
match / case (Python 3.10+)

Le "switch/case" de Python, mais en beaucoup plus puissant.

def http_status(status):
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 418:
            return "I'm a teapot"
        case 400 | 401 | 403: # (Pattern "OU")
            return "Client Error"
        case 500 | 501 | 502 | 503:
            return "Server Error"
        case _: # (Wildcard)
            return "Unknown"
3.1 Modules, Pip & Venv (L'écosystème)
Modules, Packages & import
  • Module : Un simple fichier Python (ex: utils.py).
  • Package : Un dossier de modules (ex: mon_projet/) qui contient un fichier spécial __init__.py (qui peut être vide).
# 1. Importer un module entier (de la bibliothèque standard)
import os
print(os.getcwd()) # Affiche le dossier courant

# 2. Importer un objet spécifique d'un module
from datetime import datetime, timedelta
print(datetime.now() + timedelta(days=1))

# 3. Importer son propre code
# (si mon_app/utils.py existe)
from mon_app.utils import ma_fonction

# 4. Importer avec un alias (TRÈS courant en Data Science)
import pandas as pd
df = pd.DataFrame()
pip (Package Manager) & venv (Isolation)

Problème : Projet A a besoin de django==3.0. Projet B a besoin de django==4.0. On ne peut pas les installer "globalement".
Solution : venv (Virtual Environment). Crée un "silo" (dossier) avec une installation Python isolée pour *chaque* projet.

Workflow (Cheat-sheet) :

# 1. Créer l'environnement virtuel (dans le dossier 'venv')
$ python3 -m venv venv

# 2. L'ACTIVER (change le shell)
$ source venv/bin/activate
(venv) $  <-- Le prompt change !

# 3. Installer des packages (uniquement dans 'venv')
(venv) $ pip install requests
(venv) $ pip install django

# 4. Geler les dépendances
(venv) $ pip freeze > requirements.txt

# 5. (Sur une autre machine) Installer depuis le fichier
(venv) $ pip install -r requirements.txt

# 6. Quitter l'environnement
(venv) $ deactivate
$
3.2 Écosystème (Frameworks Web)

Python est un pilier majeur du développement web back-end, avec trois frameworks dominants et un outil essentiel pour les tâches de fond.

FrameworkPhilosophieCas d'usage
Django (pip install django)"Batteries Included" (MVT).
Fournit *tout* : ORM, Admin, Auth, Routage.
Architecture MVT (Model-View-Template).
Applications complexes, CMS, ERPs.
(Ex: Instagram, Pinterest).
Flask (pip install flask)"Micro-framework".
Ne fournit que le routage et le templating (Jinja2).
Vous apportez vos propres outils (ex: SQLAlchemy pour l'ORM).
Petites APIs, microservices, projets où la flexibilité est reine.
(Ex: Netflix [partiellement]).
FastAPI (pip install fastapi)"Moderne & Rapide".
Basé sur AsyncIO (async/await) pour haute performance.
Auto-génère la documentation (OpenAPI) grâce au Type Hinting (Pydantic).
APIs modernes, microservices, applications I/O intensives (où l'on attend des BDD/APIs).
Celery (pip install celery)Gestionnaire de Tâches Asynchrones.
Permet à Django/Flask de déporter des tâches longues (emails, calculs) hors de la requête.
Envoyer un email sans bloquer l'utilisateur.
(Voir le guide "Celery").
SQLAlchemy (pip install SQLAlchemy)Le "vrai" ORM.
Une boîte à outils BDD agnostique (Core) et un ORM (Declarative).
Utilisé par Flask et FastAPI.
Tout ce qui touche à une BDD SQL de façon complexe.
3.3 Écosystème (Frameworks Data & AI)

C'est le *deuxième* pilier majeur de Python (et peut-être le plus grand aujourd'hui). Python est le langage n°1 de la Data Science et de l'IA.

LibrairieDescriptionExemple de code
NumPy (Numerical Python)La fondation. Fournit des tableaux (Arrays ndarray) N-dimensionnels ultra-rapides (écrits en C).import numpy as np
a = np.array([1, 2, 3])
print(a * 2) # [2, 4, 6]
PandasL'outil d'analyse de données. Fournit le DataFrame (un "Excel" en code). Parfait pour lire/écrire des CSV, agréger, nettoyer.import pandas as pd
df = pd.read_csv('ventes.csv')
print(df['ventes'].mean())
Matplotlib / SeabornLa bibliothèque "historique" de plotting (graphiques). Seaborn est un "wrapper" par-dessus pour de plus beaux graphiques.import matplotlib.pyplot as plt
plt.plot(df['date'], df['ventes'])
plt.show()
Jupyter (Notebooks)Un environnement web interactif (.ipynb) pour mélanger code, texte (Markdown) et graphiques. L'outil n°1 des data scientists.$ jupyter notebook
Scikit-learnLa boîte à outils n°1 du Machine Learning "classique". (Régression, Classification, Clustering).from sklearn.svm import SVC
model = SVC()
model.fit(X_train, y_train)
PyTorch (Facebook) & TensorFlow (Google)Les deux géants du Deep Learning (Réseaux de neurones).import torch
import tensorflow as tf
3.4 Outils, Plugins & Liens

Ces outils ("plugins" ou "addons") ne font pas partie du langage, mais sont *essentiels* à tout projet Python professionnel pour garantir la qualité, la maintenabilité et la reproductibilité.

Outils de Qualité de Code (Linters & Formatters)
OutilTypeDescriptionCommande
RuffLinter + FormatterLe nouveau standard (écrit en Rust). 100x plus rapide que Flake8+Black+isort réunis.$ ruff check . --fix
BlackFormatterLe "formateur d'opinion". Il ré-écrit votre code pour qu'il soit *parfaitement* formaté. "Vous pouvez avoir n'importe quel style, tant que c'est Black."$ black .
Flake8Linter (Legacy)L'ancien standard. Analyse statique qui "crie" si vous ne respectez pas les conventions (PEP 8) ou si vous avez des bugs.$ flake8 .
MyPyType CheckerAnalyse vos "Type Hints" (nom: str) et trouve les incohérences (ex: "Tu passes un int à une fonction qui attend un str").$ mypy .
Outils de Test & Dépendance
OutilTypeDescriptionCommande
PytestTest RunnerLe standard pour les tests unitaires/intégration. Plus simple et plus puissant que unittest (stdlib).$ pytest
Poetry (ou PDM)GestionnaireAlternative moderne à pip + venv + requirements.txt. Gère tout (dépendances, venv, build) dans un seul pyproject.toml.$ poetry install
Librairies "Plugins" Incontournables (PyPI)