As Felipe commented, the nomenclature of the parameter comes from keyword Arguments and, yes, it has a certain relationship with the named parameters. With the named parameters, you can set the order you want when calling 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 on Ideone | Repl.it
The use of **kwargs
is given when you do not previously know the parameters that the function will receive. When using it, you are indicating that the Python interpreter must collect all named parameters not provided in the list of arguments, 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 on Ideone | Repl.it
It is important to note that even kwargs
representing a dictionary, the order of the values is maintained the same in which it is indicated in the function parameters, thanks to the PEP 468 - Preserving the order of **kwargs in a Function.
That is, the behavior of kwargs
resembles more of a collections.OrderedDict
that a common dictionary.
But when I don’t know the parameters 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 returned, not the function itself. Since, when defining a decorator, we do not know what are the parameters that the function to be decorated defines, we use the parameters *args
and **kwargs
. Take 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 on 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
Note that when defining the function decorator decorator
, we do not know what parameters the decorated function will receive, but when using the *args
and **kwargs
ensure that all parameters are properly passed to the function.
Remember that using the parameters *args
and **kwargs
does not necessarily exclude the use of explicit parameters. That is, it is possible to use in a function both positional arguments, named and yet the *args
and **kwargs
. For example:
def foo(arg_1, arg_2, *args, arg_3=3, **kwargs):
...
But it is important to note 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 nominees.
Responding to commenting, the equivalent of doing function (...$args)
PHP 5.6+ in Python is *args
, not the **kwargs
, once while doing ...$args
you will get a array sequential with the values passed as parameters, as well as the *args
will be a list of values passed by unnamed parameters. Since PHP has no named parameters, there is no equivalent to **kwargs
python.
Additional readings
Related
In this case, these arguments with an asterisk
*args
, would be like variadic functions of PHP 5.6?– Wallace Maxters
@Wallacemaxters, I don’t know much about PHP to associate the two, but, by my understanding, it would be yes. At least when used in def. (:
– Felipe Avelar