Aliquis
Aliquis

Reputation: 2319

Python: Difference between kwargs.pop() and kwargs.get()

I have seen both ways but I do not understand what the difference is and what I should use as "best practice":

def custom_function(**kwargs):
    foo = kwargs.pop('foo')
    bar = kwargs.pop('bar')
    ...

def custom_function2(**kwargs):
    foo = kwargs.get('foo')
    bar = kwargs.get('bar')
    ...

Upvotes: 50

Views: 71757

Answers (4)

ssoler
ssoler

Reputation: 5294

Consider the next example, where the use of get or pop makes a difference:

Let's begin with get:

class Foo(object):
    def __init__(self, foo_param=None):
        print("In Foo: {}".format(foo_param))

class Bar(Foo):
    def __init__(self, **kwargs):
        bar_param = kwargs.get('bar_param')
        print("In Bar: {}".format(bar_param))
        super(Bar, self).__init__(**kwargs)

bar = Bar(foo_param='F', bar_param='B')

This code snippet raises TypeError exception:

TypeError: __init__() got an unexpected keyword argument 'bar_param'

When Bar executes super(Bar, self).__init__(**kwargs) it is forwarding to Foo the same dict he has recived: {foo_param='F', bar_param='B'}. Then Foo raises TypeError because input paramteres doesn't respect its interface.

If you pop bar_param before executing the call to super, Foo only recives its required input parameter foo_param, and all goes fine.

class Foo(object):
    def __init__(self, foo_param=None):
        print("In Foo: {}".format(foo_param))

class Bar(Foo):
    def __init__(self, **kwargs):
        bar_param = kwargs.pop('bar_param')
        print("In Bar: {}".format(bar_param))
        super(Bar, self).__init__(**kwargs)

bar = Bar(foo_param='F', bar_param='B')

Output is:

In Bar: B
In Foo: F

Upvotes: 12

Dhia
Dhia

Reputation: 10619

get(key[, default]): return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

d = {'a' :1, 'c' :2}
print(d.get('b', 0)) # return 0
print(d.get('c', 0)) # return 2

pop(key[, default]) if key is in the dictionary, remove it and return its value, else return default. If default is not given and key is not in the dictionary, a KeyError is raised.

d = {'a' :1, 'c' :2}
print(d.pop('c', 0)) # return 2
print(d) # returns {'a': 1}
print(d.get('c', 0)) # return 0

NB: Regarding best practice question, I would say it depends on your use case but I would go by default for .get unless I have a real need to .pop

Upvotes: 62

shx2
shx2

Reputation: 64328

The difference is pop also removes the item from the dict.

There is no best practice. Use the one which is more convenient for your particular use case.

Most times, all you need is getting the value.

Other times, you want to make sure no extra/unexpected kwargs are provided. In this case, it is convenient to use pop. E.g.:

a = kw.pop('a')
b = kw.pop('b')
if kw:
    raise TypeError('Unepxected kwargs provided: %s' % list(kw.keys()))

Upvotes: 16

hwhite4
hwhite4

Reputation: 715

So the get and pop functions do very different things

get is used to return a value for a given key in the dictionary

pop removes the value from the dictionary and returns the removed value

All of the dictionary functions are documented here (for python3): https://docs.python.org/3/library/stdtypes.html#mapping-types-dict

Upvotes: 6

Related Questions