Python: Difference between kwargs.pop() and kwargs.get()
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 0print(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 2print(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
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 get
ting 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()))
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: BIn Foo: F