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?


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.


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.


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é).


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.


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")

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.