*args et **kwargs

Rassembler un nombre quelconque d’arguments positionnels dans un tuple et d’arguments nommés dans un dictionnaire, et dépaqueter des collections lors d’un appel.

Sur cette page

Exemple

#
Python
def show(*args, **kwargs):
    print(args)
    print(kwargs)

show(7, "Safari", guide="Darwin", modules=12)

def log(level, *messages, **context):
    line = f"[{level}] " + " ".join(str(m) for m in messages)
    if context:
        line += " " + str(context)
    print(line)

log("INFO", "Module", 3, "terminé")
log("WARN", "Plus de carburant", user="lea", fuel=0)
Résultatrésultat enregistré, vous pouvez le vérifier
(7, 'Safari')
{'guide': 'Darwin', 'modules': 12}
[INFO] Module 3 terminé
[WARN] Plus de carburant {'user': 'lea', 'fuel': 0}

Définition et utilisation

#

Un paramètre précédé d’une étoile, habituellement *args, rassemble tous les arguments positionnels en trop dans un tuple. Un paramètre précédé de deux étoiles, **kwargs, rassemble les arguments nommés en trop dans un dictionnaire. Grâce à eux, une fonction accepte un nombre quelconque d’arguments, comme les fonctions intégrées print() ou max().

Ce sont les étoiles qui comptent, pas les noms : vous pouvez tout aussi bien écrire *scores ou **options. L’ordre dans la définition est fixe : paramètres ordinaires, *args, paramètres uniquement nommés et, tout à la fin, **kwargs. Les paramètres placés après *args ou après une étoile seule * ne peuvent être donnés que par leur nom, et ceux placés avant le signe / que par leur position.

Les étoiles fonctionnent aussi dans l’autre sens, lors de l’appel d’une fonction : *liste répartit une collection en arguments positionnels distincts, et **dictionnaire en arguments nommés. En combinant les deux techniques, vous transmettez tous les arguments sans avoir à les connaître. C’est ce qui sert de base aux décorateurs et aux classes dérivées qui passent leurs paramètres à super().__init__().

Syntaxe

#
Syntaxe
def fonction(a, b=0, *args, c, d=1, **kwargs):
    ...

fonction(*liste, **dictionnaire)

Éléments de la syntaxe

#
  • *args

    tuple

    Les arguments positionnels en trop, rassemblés dans un tuple. S’il n’y en a pas, le tuple est vide.
  • **kwargs

    dict

    Les arguments nommés en trop, sous forme de dictionnaire {nom: valeur}. S’il n’y en a pas, le dictionnaire est vide.
  • *

    séparateur

    Une étoile seule dans la définition : tous les paramètres suivants doivent être donnés par leur nom.
  • /

    séparateur

    Les paramètres placés avant la barre oblique ne peuvent être donnés que par position, sans nom.

Plus d’exemples

#
Dépaquetage lors de l’appel
Python
def create_account(name, world, level=1):
    return f"{name}, monde {world}, niveau {level}"

row = ["Léa", 7]
settings = {"world": 2, "level": 5}

print(create_account(*row))
print(create_account("Lucas", **settings))

scores = [72, 95, 64]
print(*scores)
print(max(*scores, 80))
Résultatrésultat enregistré, vous pouvez le vérifier
Léa, monde 7, niveau 1
Lucas, monde 2, niveau 5
72 95 64
95
Paramètres uniquement positionnels et uniquement nommés
Python
def award(name, /, exp, *, reason="tâche"):
    return f"{name}: +{exp} EXP ({reason})"

print(award("Léa", 20))
print(award("Lucas", exp=15, reason="série"))

try:
    award("Emma", 10, "bonus")
except TypeError as error:
    print(error)
Résultatrésultat enregistré, vous pouvez le vérifier
Léa: +20 EXP (tâche)
Lucas: +15 EXP (série)
award() takes 2 positional arguments but 3 were given
Transmettre les arguments plus loin
Python
class User:
    def __init__(self, name, email=None):
        self.name = name
        self.email = email

class Student(User):
    def __init__(self, *args, world=1, **kwargs):
        super().__init__(*args, **kwargs)
        self.world = world

emma = Student("Emma", email="emma@example.com", world=7)
print(emma.name, emma.email, emma.world)
Résultatrésultat enregistré, vous pouvez le vérifier
Emma emma@example.com 7

Bonnes pratiques

#
  • N’abusez pas de **kwargs dans les fonctions ordinaires. Des paramètres listés explicitement sont plus lisibles, et l’éditeur les suggère lors de l’appel et repère les fautes de frappe.
  • Les étoiles fonctionnent aussi dans les littéraux : [*a, *b] fusionne des listes, et {**defaults, **options} fusionne des dictionnaires. En cas de clé en double, la valeur de droite l’emporte.
  • Les paramètres placés après l’étoile seule * imposent de les donner par leur nom. C’est utile pour des options comme force=True, qui seraient incompréhensibles sans leur nom.

Entrées associées

#

Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.