MFormations
Modern Python Engineering

Chapitre 0

00-Introduction

00-Introduction

Introduction à Python — Cours Complet

1. Histoire de Python (1991–2024)

Les débuts (1989–1994)

Python a été conçu à la fin des années 1980 par Guido van Rossum au Centrum Wiskunde & Informatica (CWI) aux Pays-Bas. Le développement a commencé en décembre 1989, et la première version (0.9.0) a été publiée le 20 février 1991.

# Python 0.9.0 features already included:
# - Classes with inheritance
# - Exception handling
# - Functions (def)
# - Modules
# - Built-in types: list, dict, str

Les grandes étapes

AnnéeVersionInnovations majeures
19941.0lambda, map, filter, reduce
20002.0Unicode, list comprehensions, garbage collection
20083.0Print function, division, Unicode strings
20102.7Dernière version de la branche 2.x
20203.8Walrus operator :=
20213.10Pattern matching (structural)
20223.11Zero-cost exceptions, significantly faster
20233.12Typing improvements, free-threaded mode
20243.13JIT compiler (experimental), improved error messages

La transition Python 2 → 3 (2008–2020)

La transition a duré 12 ans. Python 2.7 a été maintenu jusqu'au 1er janvier 2020. Les principales différences :

# Python 2
print "Hello"
raw_input("Name: ")
unicode(u"text")
/ -> integer division

# Python 3
print("Hello")
input("Name: ")
str("text")
/ -> float division, // for integer

2. Le Zen de Python (PEP 20)

Écrit par Tim Peters en 1999, le Zen de Python décrit la philosophie du langage :

import this
# Beautiful is better than ugly.
# Explicit is better than implicit.
# Simple is better than complex.
# Complex is better than complicated.
# Flat is better than nested.
# Sparse is better than dense.
# Readability counts.
# Special cases aren't special enough to break the rules.
# Although practicality beats purity.
# Errors should never pass silently.
# Unless explicitly silenced.
# In the face of ambiguity, refuse the temptation to guess.
# There should be one-- and preferably only one --obvious way to do it.
# Although that way may not be obvious at first unless you're Dutch.
# Now is better than never.
# Although never is often better than *right* now.
# If the implementation is hard to explain, it's a bad idea.
# If the implementation is easy to explain, it may be a good idea.
# Namespaces are one honking great idea -- let's do more of those!

Principes clés appliqués

Explicit over implicit :

# Bad - implicit
def process(d):
    return [x for x in d if x]

# Good - explicit
def process(data: list[int]) -> list[int]:
    return [item for item in data if item > 0]

Readability counts :

# Bad
def f(x):return[x*i for i in range(x)]

# Good
def multiplication_table(size: int) -> list[int]:
    return [size * i for i in range(size)]

3. L'Écosystème Python

PyPI (Python Package Index)

PyPI héberge plus de 500 000 paquets. C'est le dépôt officiel de paquets Python.

Pip

# Installation de base
pip install requests
pip install "fastapi>=0.100.0,<1.0.0"
pip install -r requirements.txt
pip install -e .  # editable mode (development)

# Gestion avancée
pip freeze > requirements.txt
pip list --outdated
pip cache purge

Poetry — Gestionnaire de dépendances moderne

# Installation
pip install poetry

# Initialisation
poetry new my-project
poetry init

# Dépendances
poetry add fastapi uvicorn
poetry add --dev pytest pytest-cov
poetry install

# Virtualenv
poetry shell
poetry env info
# pyproject.toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["Your Name <email@example.com>"]

[tool.poetry.dependencies]
python = "^3.12"
fastapi = "^0.100.0"
uvicorn = "^0.23.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
pytest-cov = "^4.1.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Conda

Pour la science des données et le ML :

conda create -n myenv python=3.12
conda activate myenv
conda install numpy pandas matplotlib
conda install -c conda-forge jupyterlab

4. Python 3.12+ : Les nouveautés

Pattern Matching (3.10+, amélioré en 3.12)

def process_command(command: str) -> str:
    match command.split():
        case ["quit"]:
            return "Goodbye!"
        case ["hello", name]:
            return f"Hello, {name}!"
        case ["load", filename] if filename.endswith(".json"):
            return f"Loading JSON: {filename}"
        case ["load", filename]:
            return f"Loading: {filename}"
        case _:
            return "Unknown command"

# Matching sur structures de données
def analyze_point(point: tuple[int, int]) -> str:
    match point:
        case (0, 0):
            return "Origin"
        case (0, y):
            return f"On Y axis at {y}"
        case (x, 0):
            return f"On X axis at {x}"
        case (x, y) if x == y:
            return "On diagonal"
        case (x, y):
            return f"Point ({x}, {y})"

Typage amélioré (3.12)

from typing import override

class Base:
    def greet(self) -> str:
        return "Hello"

class Child(Base):
    @override  # vérifie qu'on override bien une méthode parente
    def greet(self) -> str:
        return "Hi"

# Type parameter syntax (3.12)
def first[T](items: list[T]) -> T:
    return items[0]

class Stack[T]:
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

Free-threaded Python (3.13, expérimental en 3.12)

# Installation de la version free-threaded
# Désactive le GIL (Global Interpreter Lock)
python3.13t -X gil=0
# Threading sans GIL
import threading
import time

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(1000000):
        with lock:
            counter += 1

# Avec free-threaded, les opérations atomiques
# n'ont pas besoin de lock
threads = [threading.Thread(target=increment) for _ in range(4)]
for t in threads: t.start()
for t in threads: t.join()

5. Domaines d'Application

Web Development

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.post("/items/")
async def create_item(item: Item) -> Item:
    return item

Data Science

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": np.random.randn(1000),
    "B": np.random.randn(1000),
})
df["C"] = df["A"] + df["B"]

Machine Learning

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y)
model = RandomForestClassifier()
model.fit(X_train, y_train)

DevOps & CLI

import typer
import rich

app = typer.Typer()

@app.command()
def hello(name: str) -> None:
    """Say hello to someone."""
    rich.print(f"[bold green]Hello, {name}![/bold green]")

if __name__ == "__main__":
    app()

6. Roadmap d'Apprentissage

Parcours recommandé

Semaine 1-2  : Fondamentaux (variables, types, contrôle)
Semaine 3-4  : Fonctions, décorateurs, générateurs
Semaine 5-6  : Programmation orientée objet avancée
Semaine 7-8  : Typage statique et patterns
Semaine 9-10 : Programmation asynchrone
Semaine 11-12: Tests et qualité
Semaine 13-15: Web (FastAPI, Django)
Semaine 16-17: APIs (REST, GraphQL)
Semaine 18-19: Bases de données
Semaine 20-22: Data Science
Semaine 23-24: Projet final

Ressources essentielles

ESSENTIAL_RESOURCES = {
    "docs": "https://docs.python.org/3/",
    "pep": "https://peps.python.org/",
    "pypi": "https://pypi.org/",
    "awesome": "https://github.com/vinta/awesome-python",
    "style": "PEP 8, PEP 257 (docstrings)",
    "typing": "PEP 484, 526, 604, 695",
    "async": "PEP 492, 525, 530",
}

7. Bonnes Pratiques Fondamentales

Structure de projet

my_project/
├── pyproject.toml
├── README.md
├── src/
│   └── my_project/
│       ├── __init__.py
│       ├── main.py
│       ├── models.py
│       └── utils.py
├── tests/
│   ├── __init__.py
│   ├── test_main.py
│   └── conftest.py
├── docs/
├── scripts/
└── .github/
    └── workflows/

Conventions de code

# PEP 8 - Naming conventions
MODULE_CONSTANT = 42
class_class_name: type  # PascalCase
function_name: type     # snake_case
variable_name: type     # snake_case
_private: type          # underscore prefix
__mangled: type         # double underscore

# Type hints (PEP 484)
def process_data(
    items: list[int],
    callback: Callable[[int], bool],
) -> dict[str, list[int]]:
    ...

8. Conclusion

Python 3.12+ représente la maturité du langage : performance accrue, typage robuste, écosystème riche. Ce cours vous guidera à travers tous les aspects de l'ingénierie Python moderne, des fondamentaux aux patterns avancés.

Points clés à retenir

  1. Python privilégie la lisibilité et l'explicite
  2. L'écosystème (PyPI, poetry) est mature et fiable
  3. Le typage statique est devenu un élément central
  4. Python couvre tous les domaines du développement moderne
  5. La communauté suit des conventions strictes (PEP)