web-dev-qa-db-fra.com

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

Python 3.2.3. Il y avait quelques idées listées ici , qui fonctionnent sur des variables régulières, mais il semble que ** les kwargs fonctionnent 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 ça ne ...

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

Je devine parce que kwargs est iterable? Dois-je parcourir cette liste pour vérifier si une clé est présente?

83
Zamphatta

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, kwargs n'est qu'un autre dict. Votre premier exemple, if kwargs['errormessage'], Signifie "récupérez la valeur associée à la clé" errormessage "dans kwargs, puis vérifiez sa valeur bool". Donc, s'il n'y a pas de telle clé, vous aurez un KeyError.

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

Je devrais mentionner que les dictionnaires ont aussi 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") renvoie la valeur si cette clé existe et None sinon (de manière similaire kwargs.get("errormessage", 17) fait ce que vous pourriez penser). Lorsque vous ne vous souciez pas de la différence entre la clé existante et le fait d'avoir None en tant que valeur ou la clé inexistante, cela peut être pratique.

124
DSM

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

Dans mes scripts, j'utilise souvent la fonction pratique dict.pop() pour traiter les arguments facultatifs et supplémentaires. Voici un exemple d'un wrapper print() 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 constater, si prefix ne figure pas dans kwargs, alors la valeur par défaut '' _ (chaîne vide) est stocké dans la variable locale prefix. Si elle est donnée, sa valeur est utilisée.

Il s’agit généralement d’une recette compacte et lisible permettant d’écrire des enveloppes pour n’importe quel type de fonction: limitez toujours les arguments que vous ne comprenez pas et ne savez même pas s’ils existent. Si vous passez toujours par *args et **kwargs vous ralentissez le code et nécessite 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 tous les changements d'interface.

18
cfi

C'est juste ça:

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_key Est quelque chose qui peut être passé, 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 dictionnaire kwargs (le dictionnaire contenant les arguments de mots clés).

8
Tadeck

Une façon est de l'ajouter par vous-même! Comment? En fusionnant kwargs avec un groupe de valeurs par défaut. Cela ne conviendra pas toujours, 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 inclut toutes les clés attendues. Nous vérifions d’abord s'il existe des clés inattendues dans kwargs. Ensuite, nous mettons à jour args avec kwargs, ce qui écrasera toutes les nouvelles valeurs définies par l'utilisateur. Nous n'avons pas besoin de tester si une clé existe, nous utilisons maintenant args comme dictionnaire d'arguments et n'avons plus besoin de kwargs.

2
cdarke

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")
1
Christian Thieme