Cours

Les fonctions sont une composante essentielle du langage Python : vous avez probablement déjà croisé et utilisé certaines des nombreuses fonctions natives proposées par Python ou par son vaste écosystème de bibliothèques. Cependant, en tant que data scientist, vous aurez très souvent besoin d’écrire vos propres fonctions pour résoudre les problèmes que vos données vous posent.
Ce tutoriel utilise la syntaxe de Python 3. Tous les exemples fonctionnent avec Python 3.10+ et ont été mis à jour pour refléter les conventions modernes (f-strings, annotations de type, paramètres uniquement positionnels et uniquement nommés). La version stable actuelle est Python 3.14.
Pour exécuter facilement vous‑même tout le code d’exemple de ce tutoriel, vous pouvez créer gratuitement un workbook DataLab avec Python préinstallé et incluant tous les extraits de code. Pour vous entraîner à écrire des fonctions Python, essayez cet exercice pratique sur DataCamp ou suivez notre cours Python Data Science Toolbox !
Les fonctions en Python
En programmation, vous utilisez des fonctions pour regrouper un ensemble d’instructions que vous souhaitez réutiliser, ou qui, en raison de leur complexité, gagnent à être isolées dans un sous‑programme appelé à la demande. Autrement dit, une fonction est un bloc de code écrit pour accomplir une tâche précise. Pour y parvenir, la fonction peut avoir besoin de plusieurs entrées… ou d’aucune. Une fois la tâche effectuée, la fonction peut retourner une ou plusieurs valeurs… ou rien du tout.
Il existe trois types de fonctions en Python :
-
Les fonctions natives, comme
help()pour obtenir de l’aide,min()pour récupérer la valeur minimale,print()pour afficher un objet dans le terminal, … Vous trouverez un aperçu plus complet ici. -
Les fonctions définies par l’utilisateur (User‑Defined Functions, UDF), que vous créez pour vous faciliter la vie ; et
-
Les fonctions anonymes, aussi appelées fonctions lambda, car elles ne sont pas déclarées avec le mot‑clé standard
def.
Fonctions vs. méthodes
Une méthode est une fonction qui fait partie d’une classe. Vous y accédez via une instance ou un objet de cette classe. Une fonction n’a pas cette contrainte : c’est simplement une fonction autonome. Cela signifie que toutes les méthodes sont des fonctions, mais que toutes les fonctions ne sont pas des méthodes.
Considérez cet exemple, où vous définissez d’abord une fonction plus(), puis une classe Summation avec une méthode sum() :
Si vous souhaitez maintenant appeler la méthode sum() qui fait partie de la classe Summation, vous devez d’abord définir une instance ou un objet de cette classe. Définissons donc un tel objet :
Rappelez‑vous que cette instanciation n’est pas nécessaire pour appeler la fonction plus() ! Vous pourriez exécuter plus(1,2) dans le bloc DataCamp Light sans aucun problème !
Paramètres vs. arguments
Les paramètres sont les noms utilisés lors de la définition d’une fonction ou d’une méthode, auxquels seront associés les arguments. En d’autres termes, les arguments sont les éléments fournis à tout appel de fonction ou de méthode, tandis que le code de la fonction ou de la méthode s’y réfère par leurs noms de paramètres.
Considérez l’exemple suivant et revenez au bloc DataCamp Light ci‑dessus : vous passez deux arguments à la méthode sum() de la classe Summation, alors que vous aviez défini trois paramètres : self, a et b.
Qu’est-il arrivé à self ?
Le premier argument de chaque méthode de classe est toujours une référence à l’instance courante de la classe, qui est ici Summation. Par convention, cet argument s’appelle self.
Cela signifie que vous ne passez pas explicitement la référence à self : self est le nom du paramètre correspondant à un argument implicite qui fait référence à l’instance via laquelle la méthode est appelée. Il est inséré implicitement dans la liste des arguments.
Comment définir une fonction : fonctions définies par l’utilisateur (UDF)
Les quatre étapes pour définir une fonction en Python sont les suivantes :
-
Utilisez le mot‑clé
defpour déclarer la fonction, suivi de son nom. -
Ajoutez des paramètres à la fonction : ils doivent se trouver entre parenthèses. Terminez la ligne par un deux‑points.
-
Ajoutez les instructions que la fonction doit exécuter.
-
Terminez par une instruction
returnsi la fonction doit produire un résultat. Sansreturn, votre fonction renverra l’objetNone.
Évidemment, vos fonctions deviendront plus complexes au fil du temps : vous pouvez y ajouter des boucles for, du contrôle de flux, etc., pour les affiner davantage :
def hello():
name = input("Enter your name: ")
if name:
print(f"Hello {name}")
else:
print("Hello World")
hello()
Dans la fonction ci‑dessus, vous demandez à l’utilisateur de saisir un nom. Si aucun nom n’est donné, la fonction affichera « Hello World ». Sinon, l’utilisateur verra un « Hello » personnalisé.
À retenir : vous pouvez définir un ou plusieurs paramètres pour votre UDF. Vous en saurez plus dans la section dédiée aux arguments de fonction. De plus, votre fonction peut retourner une ou plusieurs valeurs… ou aucune.
Apprenez Python à partir de zéro
L’instruction return
Notez que puisque votre UDF hello() affiche quelque chose, vous n’avez pas réellement besoin de le renvoyer. Il n’y aura aucune différence entre la fonction ci‑dessus et celle‑ci :
En revanche, si vous souhaitez continuer à travailler avec le résultat de votre fonction et effectuer des opérations dessus, vous devrez utiliser return pour renvoyer effectivement une valeur, comme une chaîne (string), un entier, etc. Considérez le scénario suivant, où hello() renvoie la chaîne "hello", tandis que la fonction hello_noreturn() renvoie None :
La seconde fonction provoque une erreur car vous ne pouvez effectuer aucune opération avec None. Vous obtiendrez un TypeError indiquant qu’il est impossible d’effectuer une multiplication entre NoneType (le None renvoyé par hello_noreturn()) et int (2).
Astuce : une fonction s’arrête immédiatement lorsqu’elle rencontre une instruction return, même si cela signifie qu’elle ne renverra aucune valeur :
Autre point utile avec return : vous pouvez l’utiliser pour renvoyer plusieurs valeurs. Pour cela, on utilise des tuples.
Rappel : cette structure de données est très proche d’une liste : elle peut contenir plusieurs valeurs. Cependant, les tuples sont immuables, ce qui signifie que vous ne pouvez pas modifier les éléments qu’ils contiennent ! On les construit avec des parenthèses (). Vous pouvez « dépaqueter » un tuple dans plusieurs variables à l’aide de la virgule et de l’opérateur d’affectation.
Examinez l’exemple suivant pour comprendre comment une fonction peut renvoyer plusieurs valeurs :
Remarque : l’instruction return sum, a aurait le même effet que return (sum, a) : dans le premier cas, sum et a sont en réalité empaquetés dans un tuple en coulisse !
Comment appeler une fonction
Dans les sections précédentes, vous avez déjà vu de nombreux exemples d’appel de fonction. Appeler une fonction signifie exécuter la fonction que vous avez définie — soit directement depuis l’invite Python, soit depuis une autre fonction (comme vous le verrez dans la section « Fonctions imbriquées »).
Appelez votre fonction nouvellement définie hello() en exécutant simplement hello(), comme dans le bloc DataCamp Light ci‑dessous :
Comment ajouter des docstrings à une fonction Python
Autre aspect essentiel lors de l’écriture de fonctions en Python : les docstrings. Elles décrivent ce que fait votre fonction, par exemple les calculs qu’elle réalise ou ses valeurs de retour. Ces descriptions servent de documentation afin que toute personne lisant la docstring comprenne le rôle de la fonction sans devoir parcourir tout son code.
Les docstrings se placent immédiatement après l’en‑tête de la fonction et sont encadrées par des triples guillemets. Une docstring appropriée pour votre fonction hello() serait : « Affiche \« Hello World\ » ».
def hello() -> None:
"""Prints "Hello World"."""
print("Hello World")
Remarque : les docstrings peuvent être plus détaillées que dans cet exemple. Pour les étudier de près, consultez des dépôts GitHub de bibliothèques Python telles que scikit-learn ou pandas, vous y trouverez de nombreux exemples !
Annotations de type
Étroitement liées aux docstrings — et presque aussi courantes dans le code Python moderne — les annotations de type permettent, depuis Python 3.5, d’annoter les paramètres et la valeur de retour d’une fonction avec les types attendus. Voici l’exemple le plus simple :
def plus(a: int, b: int) -> int:
return a + b
Le : int après chaque paramètre signifie « ceci doit être un entier », et le -> int après les parenthèses signifie « cette fonction renvoie un entier ». Python n’applique pas ces annotations à l’exécution — vous pouvez toujours passer une chaîne à plus() et Python ne se plaindra pas avant que quelque chose ne casse. Mais des outils comme mypy, pyright et les vérificateurs de type intégrés aux éditeurs comme VS Code et PyCharm utilisent ces indications pour détecter des bugs avant même l’exécution.
Pour des types plus complexes, vous pouvez utiliser directement les génériques intégrés (Python 3.9+) ou importer depuis le module typing :
def greet(names: list[str]) -> None:
for name in names:
print(f"Hello {name}")
def find_user(user_id: int) -> dict | None:
# returns the user dict, or None if not found
...
Arguments de fonction en Python
Vous avez vu plus haut la différence entre paramètres et arguments. En bref, les arguments sont les éléments transmis à l’appel d’une fonction ou d’une méthode, tandis que le code de celle‑ci s’y réfère par leurs noms de paramètres. Les UDF Python peuvent accepter quatre types d’arguments :
- Arguments par défaut
- Arguments requis
- Arguments nommés (keyword)
- Nombre variable d’arguments
Arguments par défaut
Les arguments par défaut prennent une valeur prédéfinie si aucune valeur n’est fournie lors de l’appel de la fonction. Vous assignez cette valeur par défaut avec l’opérateur =, comme dans l’exemple suivant :
Arguments requis
Comme leur nom l’indique, les arguments requis d’une UDF sont indispensables. Ils doivent être fournis lors de l’appel de la fonction et dans l’ordre exact, comme dans l’exemple suivant :
Vous devez fournir des arguments correspondant aux paramètres a et b pour appeler la fonction sans erreur. Si vous inversez a et b, le résultat ne changera pas, mais ce serait différent si vous modifiez plus() comme suit :
Arguments nommés (keyword)
Si vous souhaitez vous assurer d’appeler les paramètres dans le bon ordre, utilisez des arguments nommés lors de l’appel. Vous identifiez alors les arguments par le nom de leur paramètre. Reprenons l’exemple ci‑dessus pour clarifier :
Notez qu’avec des arguments nommés, vous pouvez aussi inverser l’ordre des paramètres tout en obtenant le même résultat à l’exécution :
Nombre variable d’arguments
Lorsque vous ne connaissez pas à l’avance le nombre exact d’arguments à passer à une fonction, vous pouvez utiliser la syntaxe avec *args :
L’astérisque (*) est placé avant le nom de variable qui contiendra toutes les valeurs des arguments non nommés. Remarquez que vous auriez tout aussi bien pu passer *varint, *var_int_args ou n’importe quel autre nom à la fonction plus().
Astuce : essayez de remplacer *args par un autre nom, en conservant l’astérisque. Vous verrez que le code ci‑dessus fonctionne toujours !
Vous constatez que cette fonction s’appuie sur la fonction native Python sum() pour additionner tous les arguments passés à plus().
Variables globales vs. locales
En général, les variables définies à l’intérieur du corps d’une fonction ont une portée locale, et celles définies à l’extérieur ont une portée globale. Autrement dit, les variables locales sont définies dans un bloc de fonction et ne sont accessibles qu’à l’intérieur de celle‑ci, tandis que les variables globales sont accessibles par toutes les fonctions de votre script :
Vous verrez apparaître un NameError indiquant que name 'total' is not defined lorsque vous essayez d’afficher la variable locale total définie dans le corps de la fonction. La variable init, en revanche, s’affiche sans problème.
Paramètres uniquement positionnels et uniquement nommés
Depuis Python 3.8, vous pouvez mieux contrôler la façon dont les arguments doivent être passés en utilisant deux marqueurs spéciaux dans la signature : / et *. Tout ce qui précède le / ne peut être passé que positionnellement ; tout ce qui suit le * ne peut être passé que par mot‑clé (keyword).
def greet(name, /, greeting="Hello", *, punctuation="!"):
print(f"{greeting} {name}{punctuation}")
Voici ce que cela implique à l’appel :
greet("Alice") # ok
greet("Alice", greeting="Hi") # ok
greet("Alice", "Hi", punctuation="?") # ok
greet(name="Alice") # TypeError : name est uniquement positionnel
greet("Alice", "Hi", "?") # TypeError : punctuation est uniquement nommé
Pourquoi vouloir cela ? Deux raisons principales.
D’abord, les paramètres uniquement positionnels vous permettent de les renommer plus tard sans casser le code de quiconque — puisque personne n’est autorisé à utiliser le nom du paramètre comme mot‑clé, vous êtes libre de le changer.
Ensuite, les paramètres uniquement nommés obligent les appelants à être explicites sur ce qu’ils passent, ce qui rend les appels plus lisibles lorsqu’il y a plusieurs options ou indicateurs facultatifs.
En bref, c’est un moyen propre d’imposer l’intention.
Les fonctions anonymes en Python
Les fonctions anonymes sont aussi appelées fonctions lambda en Python, car au lieu d’être déclarées avec le mot‑clé standard def, on utilise le mot‑clé lambda.
Dans le bloc DataCamp Light ci‑dessus, lambda x: x*2 est la fonction anonyme (ou lambda). x est l’argument, et x*2 est l’expression/instruction évaluée et renvoyée. Particularité : cette fonction n’a pas de nom, contrairement aux exemples vus dans la première partie de ce tutoriel. Si vous deviez écrire cette fonction en UDF, vous obtiendriez :
def double(x):
return x*2
Voyons un autre exemple de fonction lambda avec deux arguments :
On utilise des fonctions anonymes lorsqu’une fonction sans nom est nécessaire pour une courte durée et créée à l’exécution. C’est notamment utile avec filter(), map() et reduce() :
La fonction filter() filtre, comme son nom l’indique, la liste d’entrée my_list selon un critère >10. Avec map(), vous appliquez une fonction à tous les éléments de my_list. Ici, vous multipliez chaque élément par 2.
Notez que la fonction reduce() fait partie de la bibliothèque functools. Vous l’appliquez cumulativement aux éléments de my_list, de gauche à droite, pour réduire la séquence à une valeur unique, 55 dans cet exemple.
Utiliser main() comme fonction en Python
Si vous avez déjà pratiqué d’autres langages comme Java, vous savez que la fonction main est requise pour exécuter le programme. Comme vous l’avez vu ci‑dessus, ce n’est pas nécessaire en Python. En revanche, inclure une fonction main() peut être utile pour structurer votre code de manière logique : les composants les plus importants sont regroupés dans main().
Vous pouvez facilement définir une fonction main() et l’appeler comme toutes les autres fonctions ci‑dessus :
Cependant, en l’état, le code de votre fonction main() sera exécuté si vous importez ce fichier comme module. Pour éviter cela, on appelle main() lorsque __name__ == '__main__'.
Autrement dit, le code ci‑dessus devient :
Remarque : en plus de __main__, il existe une fonction __init__ qui initialise une instance de classe (un objet). En bref, c’est un constructeur/initialiseur, automatiquement appelé lors de la création d’une nouvelle instance. Avec cette fonction, l’objet nouvellement créé est assigné au paramètre self, comme vous l’avez vu plus haut. Voici un exemple :
class Dog:
"""A simple Dog class.
Args:
legs: Number of legs so that the dog can walk.
color: The color of the fur.
"""
def __init__(self, legs: int, color: str) -> None:
self.legs = legs
self.color = color
def bark(self) -> str:
return "bark" * 2
if __name__ == "__main__":
dog = Dog(4, "brown")
print(dog.bark())
Continuez à vous entraîner sur les fonctions Python
Bravo ! Vous êtes arrivé·e au bout de ce court tutoriel sur les fonctions en Python. Si vous souhaitez réviser d’autres bases de la programmation Python, ne manquez pas le cours Data Types for Data Science, où vous consoliderez et pratiquerez vos connaissances sur les listes, dictionnaires, tuples, ensembles et dates et heures.
Obtenez une certification dans le rôle de Data Scientist de vos rêves
Nos programmes de certification vous aident à vous démarquer et à prouver aux employeurs potentiels que vos compétences sont adaptées à l'emploi.

Foire aux questions sur les fonctions Python
Qu’est‑ce qu’une fonction en Python ?
Une fonction est un bloc de code réutilisable qui exécute une tâche spécifique. Elle peut prendre des entrées, les traiter et renvoyer des sorties.
Comment définit‑on une fonction en Python ?
Pour définir une fonction en Python, utilisez le mot‑clé def, donnez‑lui un nom, ajoutez des paramètres optionnels entre parenthèses, écrivez votre code puis, si nécessaire, utilisez return pour renvoyer une valeur.
Quelle est la différence entre fonctions et méthodes en Python ?
Les fonctions sont autonomes, tandis que les méthodes appartiennent à des classes. Toutes les méthodes sont des fonctions, mais toutes les fonctions ne sont pas des méthodes.
Quels sont les types de fonctions en Python ?
Python propose des fonctions natives (comme print()), des fonctions définies par l’utilisateur (vos créations) et des fonctions anonymes (les lambda de courte durée).
Quelle est la différence entre paramètres et arguments ?
Les paramètres sont des espaces réservés dans la définition de la fonction ; les arguments sont les valeurs réelles que vous lui passez à l’appel.
Qu’est‑ce qu’une fonction lambda ?
Une fonction lambda est une fonction d’une ligne, sans nom, pour des tâches rapides.
Pourquoi utiliser la fonction __main__ ?
La fonction __main__ aide à organiser votre code et garantit que certaines parties ne s’exécutent que lorsque le script est lancé directement, pas lorsqu’il est importé.
Quelle est la différence entre variables globales et locales ?
Les variables globales sont accessibles partout, tandis que les variables locales n’existent qu’à l’intérieur de leur fonction.
