web-dev-qa-db-fra.com

Ajouter un paramètre dans kwargs lors de l'appel de fonction?

Existe-t-il un moyen d'ajouter une paire clé-valeur dans les kwargs pendant l'appel de fonction?

def f(**kwargs):
    print(kwargs)

# ...

pre_defined_kwargs = {'a': 1, 'b': 2}

f(**pre_defined_kwargs, c=3)

Ou même changer les arguments existants?

f(**pre_defined_kwargs, b=3)  # replaces the earlier b=2

Ces deux exemples ne fonctionnent pas, car ils génèrent des erreurs

>>> f(**pre_defined_kwargs, c=3)
SyntaxError: invalid syntax

Pointant la virgule entre les arguments

20
Markus Meskanen

Pour Python versions <3.5, vous devez placer l'argument de mot-clé variable **kwargs en dernier ):

f(c=3, **pre_defined_kwargs)

Voir la Appels syntaxe d'expression ; dans toutes les formes de la grammaire, la règle "**" expression est placée en dernier . En d'autres termes, utiliser quoi que ce soit après la syntaxe **expression Est une erreur de syntaxe.

Si vous souhaitez mettre à jour le dictionnaire avec de nouvelles valeurs, vous pouvez utiliser dict() callable ; il peut créer une copie de votre dictionnaire existant et mettre à jour les clés en ce sens, à condition que les clés soient également valides Python identifiants (commencez par une lettre ou un trait de soulignement et ne contiennent que des lettres, des chiffres et des traits de soulignement):

f(c=3, **dict(pre_defined_kwargs, b=42))

Ici, b=42 Définit une nouvelle valeur pour la touche 'b'. Cette même syntaxe peut également être utilisée pour ajouter des clés.

Vous ne pouvez pas utiliser la même clé à la fois dans le mappage **expression Et explicitement; cela soulèvera un TypeError. Encore une fois, à partir de la documentation déjà liée:

Si la syntaxe **expression Apparaît dans l'appel de fonction, expression doit évaluer un mappage, dont le contenu est traité comme des arguments de mot-clé supplémentaires. Dans le cas d'un mot clé apparaissant à la fois dans expression et comme argument de mot clé explicite, une exception TypeError est levée.

Démo:

>>> def f(**kwargs):
...     print(kwargs)
... 
>>> pre_defined_kwargs = {'a': 1, 'b': 2}
>>> f(c=3, **pre_defined_kwargs)
{'a': 1, 'c': 3, 'b': 2}
>>> dict(pre_defined_kwargs, b=42)
{'a': 1, 'b': 42}
>>> f(c=3, **dict(pre_defined_kwargs, b=42))
{'a': 1, 'c': 3, 'b': 42}

Cette restriction a été levée à partir de Python 3.5 (grâce à PEP-448 - Généralisations de déballage supplémentaires ; vous pouvez désormais mélanger librement l'ordre des types d'arguments et utiliser plusieurs références **mapping dans un appel (en utilisant des mappages distincts). Les mots clés doivent toujours être uniques dans tous les arguments appliqués; vous ne pouvez toujours pas 'remplacer' les arguments qui apparaissent plusieurs fois.

32
Martijn Pieters
>>> f(c=3, **pre_defined_kwargs)
{'c': 3, 'a': 1, 'b': 2}
2
dm03514