How To Check If A Key in **kwargs Exists?

137,716

Solution 1

You want

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

To get the value of errormessage

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

In this way, kwargs is just another dict. Your first example, if kwargs['errormessage'], means "get the value associated with the key "errormessage" in kwargs, and then check its bool value". So if there's no such key, you'll get a KeyError.

Your second example, if errormessage in kwargs:, means "if kwargs contains the element named by "errormessage", and unless "errormessage" is the name of a variable, you'll get a NameError.

I should mention that dictionaries also have a method .get() which accepts a default parameter (itself defaulting to None), so that kwargs.get("errormessage") returns the value if that key exists and None otherwise (similarly kwargs.get("errormessage", 17) does what you might think it does). When you don't care about the difference between the key existing and having None as a value or the key not existing, this can be handy.

Solution 2

DSM's and Tadeck's answers answer your question directly.

In my scripts I often use the convenient dict.pop() to deal with optional, and additional arguments. Here's an example of a simple print() wrapper:

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

Then:

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

As you can see, if prefix is not contained in kwargs, then the default '' (empty string) is being stored in the local prefix variable. If it is given, then its value is being used.

This is generally a compact and readable recipe for writing wrappers for any kind of function: Always just pass-through arguments you don't understand, and don't even know if they exist. If you always pass through *args and **kwargs you make your code slower, and requires a bit more typing, but if interfaces of the called function (in this case print) changes, you don't need to change your code. This approach reduces development time while supporting all interface changes.

Solution 3

It is just this:

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

You need to check, if the key is in the dictionary. The syntax for that is some_key in some_dict (where some_key is something hashable, not necessarily a string).

The ideas you have linked (these ideas) contained examples for checking if specific key existed in dictionaries returned by locals() and globals(). Your example is similar, because you are checking existence of specific key in kwargs dictionary (the dictionary containing keyword arguments).

Solution 4

One way is to add it by yourself! How? By merging kwargs with a bunch of defaults. This won't be appropriate on all occasions, for example, if the keys are not known to you in advance. However, if they are, here is a simple example:

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)

The defaults are set in the dictionary args, which includes all the keys we are expecting. We first check to see if there are any unexpected keys in kwargs. Then we update args with kwargs which will overwrite any new values that the user has set. We don't need to test if a key exists, we now use args as our argument dictionary and have no further need of kwargs.

Solution 5

if kwarg.__len__() != 0:
    print(kwarg)
Share:
137,716
Zamphatta
Author by

Zamphatta

Developer that mainly uses Python 3 & the Django framework. I also have years of experience with XML, HTML, XSLT, CSS, and PHP. Tho, my PHP knowledge is old and rusty and neglected.

Updated on July 08, 2022

Comments

  • Zamphatta
    Zamphatta almost 2 years

    Python 3.2.3. There were some ideas listed here, which work on regular var's, but it seems **kwargs play by different rules... so why doesn't this work and how can I check to see if a key in **kwargs exists?

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

    I also think this should work, but it doesn't --

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

    I'm guessing because kwargs is iterable? Do I have to iterate through it just to check if a particular key is there?

    • Lennart Regebro
      Lennart Regebro almost 12 years
      There is no special rules. You just forgot the quotes.
  • cfi
    cfi almost 12 years
    Remove the "easy" and then it's a better answer. If it was easy for everybody, then we wouldn't need this site. Finding the in operator in itself is not easy if you've never programmed and/or are new to Python. It's only being hinted at in the dict.get() and dict.setdefault() help.
  • Honeybear
    Honeybear about 6 years
    Thanks for the extra explanation! Always good for python newcomers to get some background info and further examples of what is possible and what isn't. In that spirit: I think, kwargs.get("errormessage", 17) might return its value or 17 if errormessage doesn't exist - but I'm not sure. Is that correct?
  • Honeybear
    Honeybear about 6 years
    Ah yes it does. Found it here. Thanks... just wanted to be sure.
  • HBat
    HBat about 6 years
    Thanks for showing how to assign a default value to prefix.
  • Eduardo Lucio
    Eduardo Lucio over 3 years
    Simple and interactive! Thanks! =D
  • mhand
    mhand over 3 years
    I really love the pass through behavior when wrapping functions -- it makes this technique particularly robust in the face of future updates to wrapped functions.
  • PatrickT
    PatrickT over 2 years
    To clarify: isn't if some_key in kwargs: more like if some_key in some_dict.keys():? In other words, isn't kwargs more like an unpacked dictionary?
  • PatrickT
    PatrickT over 2 years
    Oh wait! you have a related answer which clarifies things quite a bit: stackoverflow.com/questions/10491027/…