Reputation: 2319
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
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
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
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 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()))
Upvotes: 16
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