Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutability of the **kwargs argument in Python

Consider a case where I change the kwargs dict inside a method:

def print_arg(**kwargs):
    print kwargs.pop('key')

If I call the method pop_arg with a dictionary like this:

mydict = {'key':'value'}
print_arg(**mydict)

will mydict be changed by this call?

I am also interested in a more detailed explanation of the underlying method calling mechanism that lets mydict change or not.

like image 874
silvado Avatar asked Apr 16 '13 14:04

silvado


People also ask

What is the correct way to use the Kwargs statement?

The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks ( ** ) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

How do you define keyword arguments in Python?

Keyword arguments (or named arguments) are values that, when passed into a function, are identifiable by specific parameter names. A keyword argument is preceded by a parameter and the assignment operator, = . Keyword arguments can be likened to dictionaries in that they map a value to a keyword. A. A.

Can you have Kwargs without args?

Python is pretty flexible in terms of how arguments are passed to a function. The *args and **kwargs make it easier and cleaner to handle arguments. The important parts are “*” and “**”. You can use any word instead of args and kwargs but it is the common practice to use the words args and kwargs.

How do you pass multiple Kwargs?

Python 3.5+ allows passing multiple sets of keyword arguments ("kwargs") to a function within a single call, using the `"**"` syntax.


2 Answers

No, mydict won't be changed. kwargs get unpacked into a new dictionary.

Consider the case where you have:

def print_arg(key=1, **kwargs):
    print(key)
    print(kwargs)

print_arg(**{'key':2,'foo':3,'bar':4})

In this case, it's obvious that kwargs is a different dict than you pass in because when it gets unpacked, it's missing the 'key' key.

like image 158
mgilson Avatar answered Nov 08 '22 03:11

mgilson


@mgilson's answer is correct. But you should also be aware about the shallow copy.

def print_arg(**kwargs):
    print kwargs.pop('key')
    kwargs['list'].pop()  # will affect the original
    kwargs['dict'].pop('a') #will affect the original

mydict = {'key':'value', 'list':[2,3,4,5] ,'dict': { 'a':1,'b':2 }}
print_arg(**mydict)
print (mydict)  # Output : {'dict': {'b': 2}, 'list': [2, 3, 4], 'key': 'value'}

http://codepad.org/diz38tWF

like image 41
DhruvPathak Avatar answered Nov 08 '22 04:11

DhruvPathak