Comment vérifier si une clé dans ** kwargs existe?

111

Python 3.2.3. Il y avait quelques idées énumérées ici , qui fonctionnent sur les var régulières, mais il semble que les ** kwargs jouent selon des règles différentes ... alors pourquoi cela ne fonctionne-t-il pas et comment puis-je vérifier si une clé dans ** kwargs existe?

if kwargs['errormessage']:
    print("It exists")

Je pense aussi que cela devrait fonctionner, mais ce n'est pas le cas -

if errormessage in kwargs:
    print("yeah it's here")

Je suppose que kwargs est itérable? Dois-je le parcourir simplement pour vérifier si une clé particulière est présente?

Zamphatta
la source
4
Il n'y a pas de règles spéciales. Vous venez d'oublier les citations.
Lennart Regebro

Réponses:

164

Tu veux

if 'errormessage' in kwargs:
    print("found it")

Pour obtenir la valeur de errormessage

if 'errormessage' in kwargs:
    print("errormessage equals " + kwargs.get("errormessage"))

De cette façon, kwargsest juste un autre dict. Votre premier exemple, if kwargs['errormessage']signifie "obtenir la valeur associée à la clé" message d'erreur "dans kwargs, puis vérifier sa valeur booléenne". Donc, s'il n'y a pas de clé, vous obtiendrez un fichier KeyError.

Votre deuxième exemple, if errormessage in kwargs:signifie "si kwargscontient l'élément nommé par" errormessage", et à moins que" errormessage"soit le nom d'une variable, vous obtiendrez un NameError.

Je dois mentionner que les dictionnaires ont également une méthode .get()qui accepte un paramètre par défaut (lui-même par défaut None), de sorte que kwargs.get("errormessage")retourne la valeur si cette clé existe et Nonesinon (fait de même kwargs.get("errormessage", 17)ce que vous pourriez penser qu'elle fait). Lorsque vous ne vous souciez pas de la différence entre la clé existante et ayant Nonecomme valeur ou la clé inexistante, cela peut être pratique.

DSM
la source
Merci pour l'explication supplémentaire! Il est toujours bon pour les nouveaux arrivants de python d'obtenir des informations générales et d'autres exemples de ce qui est possible et de ce qui ne l'est pas. Dans cet esprit: je pense, kwargs.get("errormessage", 17)pourrait renvoyer sa valeur ou 17si le message d'erreur n'existe pas - mais je ne suis pas sûr. Est-ce exact?
Honeybear
Ah oui. Je l'ai trouvé ici . Merci ... je voulais juste être sûr.
Honeybear
21

Les réponses de DSM et de Tadeck répondent directement à votre question.

Dans mes scripts, j'utilise souvent le pratique dict.pop()pour traiter des arguments optionnels et supplémentaires. Voici un exemple de print()wrapper simple :

def my_print(*args, **kwargs):
    prefix = kwargs.pop('prefix', '')
    print(prefix, *args, **kwargs)

Ensuite:

>>> my_print('eggs')
 eggs
>>> my_print('eggs', prefix='spam')
spam eggs

Comme vous pouvez le voir, si prefixn'est pas contenu dans kwargs, alors la valeur par défaut ''(chaîne vide) est stockée dans la prefixvariable locale . Si elle est donnée, alors sa valeur est utilisée.

C'est généralement une recette compacte et lisible pour écrire des wrappers pour tout type de fonction: il suffit toujours de passer des arguments que vous ne comprenez pas, et que vous ne savez même pas s'ils existent. Si vous passez toujours *argset que **kwargsvous ralentissez votre code et que vous avez besoin d'un peu plus de frappe, mais si les interfaces de la fonction appelée (dans ce cas print) changent, vous n'avez pas besoin de changer votre code. Cette approche réduit le temps de développement tout en prenant en charge toutes les modifications d'interface.

cfi
la source
Merci d'avoir montré comment attribuer une valeur par défaut à prefix.
HBat
11

C'est juste ceci:

if 'errormessage' in kwargs:
    print("yeah it's here")

Vous devez vérifier si la clé est dans le dictionnaire. La syntaxe pour cela est some_key in some_dict(où some_keyest quelque chose de hachable, pas nécessairement une chaîne).

Les idées que vous avez liées ( ces idées ) contenaient des exemples permettant de vérifier si une clé spécifique existait dans les dictionnaires renvoyés par locals()et globals(). Votre exemple est similaire, car vous vérifiez l'existence d'une clé spécifique dans le kwargsdictionnaire (le dictionnaire contenant des arguments de mot-clé).

Tadeck
la source
3

Une façon est de l'ajouter vous-même! Comment? En fusionnant kwargsavec un tas de valeurs par défaut. Cela ne sera pas approprié en toutes occasions, par exemple, si les clés ne vous sont pas connues à l'avance. Cependant, s'ils le sont, voici un exemple simple:

import sys

def myfunc(**kwargs):
    args = {'country':'England','town':'London',
            'currency':'Pound', 'language':'English'}

    diff = set(kwargs.keys()) - set(args.keys())
    if diff:
        print("Invalid args:",tuple(diff),file=sys.stderr)
        return

    args.update(kwargs)            
    print(args)

Les valeurs par défaut sont définies dans le dictionnaire args, qui comprend toutes les clés que nous attendons. Nous vérifions d'abord s'il y a des clés inattendues dans kwargs. Ensuite, nous mettons à jour argsavec kwargsqui écrasera toutes les nouvelles valeurs que l'utilisateur a définies. Nous n'avons pas besoin de tester si une clé existe, nous l'utilisons maintenant argscomme dictionnaire d'arguments et n'en avons plus besoin kwargs.

cdarke
la source
1

Vous pouvez découvrir ces choses facilement par vous-même:

def hello(*args, **kwargs):
    print kwargs
    print type(kwargs)
    print dir(kwargs)

hello(what="world")
Christian Thieme
la source
13
Supprimez le "facile" et c'est une meilleure réponse. Si c'était facile pour tout le monde, nous n'aurions pas besoin de ce site. Trouver l' inopérateur en lui-même n'est pas facile si vous n'avez jamais programmé et / ou êtes nouveau sur Python. Ce n'est qu'indiqué dans le dict.get()et dict.setdefault()help.
cfi
1
if kwarg.__len__() != 0:
    print(kwarg)
YeongHwa Jin
la source