Fonctions, modules et POO

Se connecter pour s'inscrire

Votre progression

Continuez pour débloquer la suite !
0 / 0 étapes complétées 0
%

Syllabus

  1. Description

  2. Objectifs

  3. Validations de compétences

  4. Public cible

    Aucun public cible spécifié pour ce module.

  5. Besoins techniques

  6. Prérequis

    • Aucun prérequis
  7. Niveau

  8. Historique du module

    Aucune action enregistrée

Fonctions, modules et POO

  1. Fonctions

    En Python, une fonction est définie avec def, les paramètres par défaut sont évalués à la définition, et la valeur de retour est return — un return sans valeur arrête la fonction et renvoie None.

    def moyenne(notes: list[float], mention: str = "") -> float:
        """Calcule la moyenne et renvoie un message."""
        if not notes:                       # évite la division par zéro
            raise ValueError("liste de notes vide")
        moyenne = sum(notes) / len(notes)
        if mention:
            return moyenne                  # type ignore
        return moyenne, mention             # un tuple

    Valeurs par défaut mutables : l'erreur classique

    # MAUVAIS : la liste est créée une seule fois, partagée par tous les appels
    def ajouter(elt, cible=[]):
        cible.append(elt)
        return cible
    
    # BON : None par défaut, liste créée à chaque appel
    def ajouter(elt, cible=None):
        if cible is None:
            cible = []
        cible.append(elt)
        return cible

    Arguments nommés et déballage

    def afficher(nom, *, couleur="noir", taille=10):
        print(nom, couleur, taille)
    
    afficher("titre", couleur="rouge")   # lisible, l'ordre n'importe plus
    
    premier, *reste, dernier = [1, 2, 3, 4, 5]
    # premier=1, reste=[2,3,4], dernier=5

    Le * seul rend les paramètres suivants obligatoires et nommés : c'est une façon simple d'éviter les erreurs d'appel.

    Fonctions lambdas et closures

    carre = lambda x: x * x          # une seule expression
    
    def multiplier(facteur):
        def interne(x):
            return x * facteur             # « capture » du facteur
        return interne
    
    double = multiplier(2)
    print(double(21))                     # 42
  2. Classes et objets

    Une classe décrit des données et les méthodes qui les manipulent. Le constructeur est __init__, et la méthode __repr__ définit ce qui s'affiche.

    class CompteBancaire:
        """Compte avec solde contrôlé."""
    
        def __init__(self, titulaire: str, solde: float = 0.0):
            self.titulaire = titulaire
            self._solde = solde            # convention : attribut « privé »
    
        def deposer(self, montant: float) -> bool:
            if montant <= 0:
                return False
            self._solde += montant
            return True
    
        @property                       # accès en lecture
        def solde(self) -> float:
            return self._solde
    
        def __repr__(self) -> str:
            return f"Compte({self.titulaire}, {self._solde:.2f})"

    @property transforme une méthode en attribut en lecture seule : c.solde au lieu de c.get_solde(), tout en gardant le contrôle. Une classe dataclass évite d'écrire le constructeur à la main :

    from dataclasses import dataclass, field
    
    @dataclass
    class Etudiant:
        nom: str
        age: int
        cours: list[str] = field(default_factory=list)   # pas de partage !
    
    e = Etudiant("Alice", 22, ["Python"])
    print(e)          # Etudiant(nom='Alice', age=22, cours=['Python'])

    Héritage et polymorphisme

    class Forme:
        def aire(self) -> float:
            raise NotImplementedError("à redéfinir")
    
    class Cercle(Forme):
        def __init__(self, rayon: float):
            self.rayon = rayon
    
        def aire(self) -> float:
            return math.pi * self.rayon ** 2
    
    formes = [Cercle(1), Cercle(2)]
    print(sum(f.aire() for f in formes))   # la même méthode, des résultats différents

    La dernière ligne est le polymorphisme : le code ne connaît pas le type réel, il appelle aire().

  3. Modules, imports et décorateurs

    Organiser le code

    mon_projet/
    ├── main.py
    ├── outils/
    │   ├── __init__.py
    │   └── maths.py

    Importer

    from outils.maths import moyenne          # une chose précise
    import outils.maths                           # le module entier
    from outils import maths                      # le sous-module

    On importe un symbole précis plutôt qu'un module entier : on sait d'où vient chaque chose, et on évite les collisions de noms.

    La bibliothèque standard

    Avant d'écrire une fonction, vérifier si elle existe déjà : math, datetime, json, pathlib, csv, random, itertools, collections, unittest.

    import json
    with open("config.json", encoding="utf-8") as f:
        config = json.load(f)          # dict
    
    from pathlib import Path
    for fichier in Path("dossier").glob("*.txt"):
        print(fichier)

    Décorateurs

    Un décorateur est une fonction qui enveloppe une autre fonction. Il sert à la journalisation, aux mesures de temps, aux permissions.

    import functools
    import time
    
    def chronometrer(fonction):
        @functools.wraps(fonction)      # garde le nom et la docstring
        def enveloppe(*args, **kwargs):
            debut = time.perf_counter()
            try:
                return fonction(*args, **kwargs)
            finally:
                duree = (time.perf_counter() - debut) * 1000
                print(f"{fonction.__name__} : {duree:.1f} ms")
        return enveloppe
    
    @chronometrer
    def traitement():
        ...
  4. Exercices

    1. Correction du bug : ce compteur d'appels est-il correct ? Expliquez, puis corrigez.
      def compter_appels(fonction):
          appels = [0]
      
          def enveloppe(*args, **kwargs):
              appels[0] += 1
              return fonction(*args, **kwargs)
          return enveloppe
    2. Catalogue : écrivez une classe Article (nom, prix, quantité) avec une méthode total(), et une fonction qui renvoie le total d'une liste d'articles.
    3. Décorateur : écrivez un décorateur journalise qui affiche les arguments reçus avant l'appel.

Exercices, examens et projets

Exercice

Atelier Python

Écrire et tester des fonctions Python en respectant PEP 8.

Obligatoire Consulter
Examen

Examen Python

Évaluer syntaxe, structures, POO, exceptions et tests.

Obligatoire Consulter