
Fonctions avancées
Explorez les fonctionnalités avancées des fonctions en Python : fonctions lambda (anonymes), fonctions récursives, fonctions d'ordre supérieur (map, filter, reduce), et décorateurs. Développez des compétences avancées en programmation fonctionnelle.
Fonctions lambda : des fonctions anonymes et concises
Les fonctions lambda sont des fonctions anonymes (sans nom) que vous pouvez définir en une seule ligne de code. Elles sont utiles pour créer des fonctions simples et courtes, souvent utilisées comme arguments pour des fonctions d'ordre supérieur (que nous verrons plus loin).
Vous définissez une fonction lambda en utilisant le mot-clé `lambda`, suivi des paramètres (séparés par des virgules), de deux-points (`:`), et de l'expression qui constitue le corps de la fonction. La fonction lambda renvoie implicitement le résultat de l'expression.
Par exemple : `carre = lambda x: x**2`. Cette fonction lambda prend un paramètre `x` et renvoie son carré. Vous pouvez l'utiliser comme une fonction normale : `print(carre(5))` affichera `25`.
Les fonctions lambda sont limitées à une seule expression. Elles ne peuvent pas contenir de blocs d'instructions complexes. Elles sont donc adaptées aux fonctions simples, mais pas aux fonctions plus élaborées.
Nous verrons des exemples d'utilisation de fonctions lambda, et comment les combiner avec des fonctions d'ordre supérieur.
Fonctions récursives : quand une fonction s'appelle elle-même
Une fonction récursive est une fonction qui s'appelle elle-même, directement ou indirectement. La récursivité est un concept puissant qui permet de résoudre des problèmes de manière élégante et concise, en particulier les problèmes qui peuvent être décomposés en sous-problèmes similaires.
Un exemple classique de fonction récursive est la fonction factorielle : `def factorielle(n): if n == 0: return 1 else: return n * factorielle(n-1)`. Cette fonction calcule la factorielle d'un nombre `n` (le produit de tous les entiers de 1 à `n`). Si `n` est égal à 0, elle renvoie 1 (cas de base). Sinon, elle renvoie `n` multiplié par la factorielle de `n-1` (appel récursif).
Il est important de définir un cas de base (une condition d'arrêt) pour une fonction récursive, sinon elle s'appellera indéfiniment et provoquera une erreur (`RecursionError`).
La récursivité peut être plus difficile à comprendre que les boucles, mais elle peut rendre votre code plus clair et plus expressif pour certains types de problèmes. Nous verrons des exemples de fonctions récursives, et comment les utiliser efficacement.
Fonctions d'ordre supérieur : `map`, `filter`, `reduce`
Une fonction d'ordre supérieur est une fonction qui prend une ou plusieurs fonctions en argument, ou qui renvoie une fonction comme résultat. Les fonctions d'ordre supérieur sont un élément clé de la programmation fonctionnelle, un paradigme de programmation qui met l'accent sur l'utilisation de fonctions pures (sans effets de bord) et sur l'immutabilité des données.
Python propose plusieurs fonctions d'ordre supérieur intégrées, comme `map`, `filter` et `reduce`.
`map` prend une fonction et une séquence (comme une liste) en argument, et applique la fonction à chaque élément de la séquence, renvoyant une nouvelle séquence contenant les résultats. Par exemple : `carres = list(map(lambda x: x**2, [1, 2, 3]))` renvoie `[1, 4, 9]`.
`filter` prend une fonction et une séquence en argument, et renvoie une nouvelle séquence contenant uniquement les éléments pour lesquels la fonction renvoie `True`. Par exemple : `pairs = list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5]))` renvoie `[2, 4]`.
`reduce` (qui doit être importé depuis le module `functools`) prend une fonction et une séquence en argument, et applique la fonction de manière cumulative aux éléments de la séquence, de gauche à droite, de manière à réduire la séquence à une seule valeur. Par exemple : `somme = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])` renvoie `15`.
Nous verrons comment utiliser `map`, `filter` et `reduce`, comment les combiner avec des fonctions lambda, et comment les utiliser pour écrire du code concis et expressif.
Décorateurs : modifiez le comportement des fonctions
Les décorateurs sont une fonctionnalité avancée de Python qui vous permet de modifier le comportement d'une fonction sans modifier son code source. Ils sont souvent utilisés pour ajouter des fonctionnalités transversales, comme la journalisation, la gestion des erreurs, la validation des arguments, ou la mesure du temps d'exécution.
Un décorateur est une fonction qui prend une fonction en argument et renvoie une nouvelle fonction qui enveloppe (wrap) la fonction originale. La nouvelle fonction peut ajouter des instructions avant et/ou après l'exécution de la fonction originale.
Vous appliquez un décorateur à une fonction en utilisant le symbole `@` suivi du nom du décorateur, juste avant la définition de la fonction. Par exemple : `@mon_decorateur def ma_fonction(): ...`. Cela équivaut à : `ma_fonction = mon_decorateur(ma_fonction)`.
Nous verrons comment créer des décorateurs simples, comment les utiliser, et comment créer des décorateurs avec des arguments. Les décorateurs peuvent sembler complexes au premier abord, mais ils peuvent rendre votre code plus modulaire et plus facile à maintenir.