ProgrammationDéveloppeur Backend

Comment fonctionne le mécanisme de gestion des arguments positionnels et nommés (positional and keyword arguments) en Python ? Quels sont les détails concernant l'ordre des arguments lors de la définition d'une fonction et de son appel, et à quoi servent uniquement les paramètres positionnels et uniquement les paramètres nommés ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En Python, une fonction peut déclarer des paramètres de quatre types : positionnels, nommés (keyword), uniquement positionnels (positional-only) et uniquement nommés (keyword-only). Leur différence influence la manière de transmettre des valeurs lors de l'appel de la fonction.

Types de paramètres

  1. Positionnels (généralement en premier) : les valeurs sont transférées dans l'ordre spécifié.
  2. Només : spécifiés explicitement par leur nom.
  3. Uniquement positionnels : déclarés avant le caractère / (Python 3.8+), ne peuvent pas être spécifiés par leur nom.
  4. Uniquement nommés : déclarés après *, peuvent uniquement être spécifiés par clé.
# Exemples de tous les types def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Erreur : a, b - uniquement positionnels

Détails

  • Ordre des paramètres : (only-positional) / (positional-or-keyword) * (only-keyword)
  • En cas d'ordre incorrect des arguments — SyntaxError ou TypeError.
  • *args collecte des arguments positionnels supplémentaires ; **kwargs — des arguments nommés.

Question piégeuse.

Quelles sont les différences entre les déclarations de fonctions :

def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...

Est-il vrai que toutes ces fonctions peuvent être appelées à la fois avec des paramètres positionnels et nommés ?

Réponse :

  • Pour la fonction def f(a, b, c):, il n'est pas possible d'appeler avec uniquement des arguments nommés, car tous peuvent être fournis soit par position, soit par clé, mais tous les arguments sont obligatoires.
  • Il est possible de spécifier les paramètres par leur nom, s'ils ne sont pas définis comme uniquement positionnels.
  • Si la fonction est déclarée comme def f(a, b, /, c):, alors a et b ne peuvent être fournis que par position.

Exemple :

def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 par défaut f(a=1, b=2, c=3) # OK # Or : def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # Erreur ! a et b uniquement par position

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire

Un développeur a implémenté une fonction qui, selon la convention, doit prendre des paramètres uniquement par nom : journalisation avec de nombreux paramètres, dont certains sont optionnels. Mais il a oublié de déclarer * — et les utilisateurs passaient accidentellement des paramètres dans un ordre différent par position, ce qui entraînait une journalisation incorrecte et des erreurs difficiles à suivre.


Histoire

Dans un projet avec une API REST, en raison d'une convention implicite sur l'ordre des arguments (utilisation de *args et absence de restriction sur les paramètres par nom), les requêtes ont cessé de fonctionner après le déploiement d'une nouvelle version du client — car args ont été décalés. Cela a été corrigé par l'introduction de * explicites et en ne permettant que des arguments nommés.


Histoire

Dans un grand projet d'entreprise, la fonction a été élargie avec de nouveaux paramètres avec des valeurs par défaut, mais en raison d'un appel erroné avec des valeurs positionnelles, l'ancien code a commencé à passer des valeurs à d'autres paramètres, ce qui a entraîné un traitement incorrect des données. Il s'est avéré que les paramètres devaient être uniquement nommés.