Supposons que j'ai une fonction, f
:
def f (a=None):
print a
Maintenant, si j'ai un dictionnaire tel que dct = {"a":"Foo"}
, Je peux appeler f(**dct)
et obtenir le résultat Foo
imprimé.
Cependant, supposons que j'ai un dictionnaire dct2 = {"a":"Foo", "b":"Bar"}
. Si j'appelle f(**dct2)
j'obtiens un
TypeError: f() got an unexpected keyword argument 'b'
C'est suffisant. Cependant, existe-t-il de toute façon, dans la définition de f
ou dans son appel, de dire Python d'ignorer simplement les clés qui ne sont pas des noms de paramètres? De préférence une méthode qui permet de spécifier les valeurs par défaut.
En tant qu'extension de la réponse publiée par @Bas, je suggérerais d'ajouter les arguments kwargs (arguments de mots clés de longueur variable) comme deuxième paramètre de la fonction
>>> def f (a=None, **kwargs):
print a
>>> dct2 = {"a":"Foo", "b":"Bar"}
>>> f(**dct2)
Foo
Cela suffirait nécessairement au cas
Cela peut être fait en utilisant **kwargs
, qui vous permet de collecter tous les arguments de mots clés non définis dans un dict:
def f(**kwargs):
print kwargs['a']
Test rapide:
In [2]: f(a=13, b=55)
13
[~ # ~] modifier [~ # ~] Si vous souhaitez toujours utiliser les arguments par défaut, vous conservez l'argument d'origine avec la valeur par défaut, mais vous ajouter le **kwargs
pour absorber tous les autres arguments:
In [3]: def f(a='default_a', **kwargs):
...: print a
...:
In [4]: f(b=44, a=12)
12
In [5]: f(c=33)
default_a
Si vous ne pouvez pas modifier la définition de la fonction pour prendre des kwargs ** non spécifiés, vous pouvez filtrer le dictionnaire que vous transmettez par les arguments de mot-clé en utilisant la fonction argspec dans les anciennes versions de python ou la méthode d'inspection de signature dans Python 3.6.
import inspect
def filter_dict(dict_to_filter, thing_with_kwargs):
sig = inspect.signature(thing_with_kwargs)
filter_keys = [param.name for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD]
filtered_dict = {filter_key:dict_to_filter[filter_key] for filter_key in filter_keys}
return filtered_dict
def myfunc(x=0):
print(x)
mydict = {'x':2, 'y':3}
filtered_dict = filter_dict(mydict, myfunc)
myfunc(**filtered_dict) # 2
myfunc(x=3) # 3