What does KWARGS mean in Python?

5

I know that in Python we can define in a function something like what we call "named parameters", that is, "named parameters".

def my_func(**kwargs):
    pass

my_func(nome="Stack Overflow", linguagem="Português")

I do not know if my definition of "named parameters" really is the same goal as the argument kwargs of the function parameter (at least for me, it looks like it is, and if it is not, I'd like you to correct me) .

But in practice, what would be the "KW" of this kwargs ?

Is it a dict or is it another object?

    
asked by anonymous 24.06.2015 / 13:23

2 answers

4

In fact, as can be seen in this SOen response , the question is more related to the syntax of an asterisk and two asterisks. When you use two asterisks, you will pass dict , as you yourself quoted.

The kwargs is just a convention for K and w Arg uments (named parameters, as you assumed), but variable can be any name. If you want to pass an indefinite number of parameters, but without naming them, you would only use an asterisk in the definition.

    
24.06.2015 / 13:35
3

As Felipe commented, the parameter's nomenclature comes from keyword arguments and, rather, has a certain relation to the named parameters. With named parameters, you can define the order you want when invoking a function or method. For example:

def fullname(firstname, lastname):
    return " ".join([firstname, lastname])

print(fullname("Anderson", "Woss"))  # Anderson Woss
print(fullname(lastname="Masters", firstname="Wallace"))  # Wallace Maxters

See working at Ideone | Repl.it

The use of **kwargs occurs when you do not know the parameters that the function will receive beforehand. When using it, you are indicating that the Python interpreter must collect all the named parameters not provided in the argument list, but that were passed when invoking the function / method, creating a dictionary called kwargs .

def fullname(firstname, **kwargs):
    return " ".join([firstname] + list(kwargs.values()))

print(fullname(firstname="Anderson"))  # Anderson
print(fullname(firstname="Anderson", middlename="Carlos", lastname="Woss"))  # Anderson Carlos Woss

See working at Ideone | Repl.it

It is important to note that even kwargs representing a dictionary, the order of values is kept the same as it is indicated in the function parameters, thanks to PEP 468 - Preserving the order of ** kwargs in a function .  That is, the behavior of kwargs is more like collections.OrderedDict than a common dictionary.

But when I do not know the parameters that the function will receive?

One of the main uses of *args and **kwargs is in the definition of decorators. By definition, a decorator will always return a function that will represent the decorated function in the context in which it was defined. That is, when I call a decorated function, what will be executed in the first instance is the function that the decorator has returned, not the function itself. Since, when defining a decorator, we do not know what parameters the function to be decorated defines, we use the parameters *args and **kwargs . Here's an example:

def decorator(function):
    def wrapper(*args, **kwargs):
        print("Antes de chamar a função", function.__name__)
        function(*args, **kwargs)
        print("Depois de chamar a função", function.__name__)
    return wrapper

@decorator
def foo(name):
    print(name)

@decorator
def bar(number):
    print(2*number)

foo("Anderson")
bar(2)

See working at Ideone | Repl.it

The result will be:

Antes de chamar a função foo
Anderson
Depois de chamar a função foo
Antes de chamar a função bar
4
Depois de chamar a função bar

Notice that when we define the decorator function decorator , we do not know what parameters the decorated function will receive, but when using the *args and **kwargs we ensure that all parameters are properly passed to the function. p>

Note that using the parameters *args and **kwargs does not necessarily exclude the use of explicit parameters. That is, you can use in a function both positional, named arguments and even the *args and **kwargs . For example:

def foo(arg_1, arg_2, *args, arg_3=3, **kwargs):
    ...

But it is important to point out that the order, in this case, should always be:

  • Positional arguments;
  • *args ;
  • Named arguments;
  • **kwargs ;
  • This is because Python requires that positional parameters always come before the named ones.

    Responding to the comment , the equivalent make function (...$args) of PHP 5.6+ in Python is *args , not **kwargs , since doing ...$args will get a sequential array with values passed as parameters, so as *args will be a list with values passed by unnamed parameters. Since PHP does not have named parameters, there is no equivalent to **kwargs of Python.

    Additional readings

    Related

    27.10.2017 / 01:55