2022-05-27 06:47:27 -05:00
# About
For the basics on function arguments, please see the [function concept][function concept].
## Parameter Names
Paramater names, like variable names, must start with a letter or underscore and may contain letters, underscores, or numbers.
Parameter names should not contain spaces or punctuation.
## Positional Arguments
2022-05-31 17:31:10 -05:00
Positional arguments are values passed to a function in the same order as the parameters which bind to them.
Positional arguments can optionally be called by using their name.
2022-05-27 06:47:27 -05:00
2022-05-28 13:27:19 -05:00
Following is an example of positional arguments being called by position and by their name:
2022-05-27 06:47:27 -05:00
```python
2022-05-30 15:22:31 -05:00
>>> def concat(greeting, name):
... return f"{greeting}{name}"
2022-05-29 06:49:57 -05:00
...
2022-05-31 16:51:23 -05:00
# Passing data to the function by position.
2022-05-27 06:47:27 -05:00
>>> print(concat("Hello, ", "Bob"))
2022-05-31 16:51:23 -05:00
2022-05-27 06:47:27 -05:00
Hello, Bob
2022-05-30 15:22:31 -05:00
>>> print(concat(name="Bob", greeting="Hello, "))
2022-05-27 06:47:27 -05:00
Hello, Bob
```
The first call to `concat` passes the arguments by position.
2022-05-28 13:27:19 -05:00
The second call to `concat` passes the arguments by name, allowing their positions to be changed.
2022-05-27 06:47:27 -05:00
2022-05-27 06:56:56 -05:00
Note that positional arguments cannot follow keyword arguments.
This
```python
2022-05-30 15:22:31 -05:00
>>> print(concat(greeting="Hello, ", "Bob"))
2022-05-27 06:56:56 -05:00
```
results in this error:
```
SyntaxError: positional argument follows keyword argument
```
2022-05-27 06:47:27 -05:00
Arguments can be forced to be positional-only through the use of the `/` operator.
Following is an example of positional-only arguments:
```python
2022-05-30 15:22:31 -05:00
>>> def concat(greeting, name, /):
... return f"{greeting}{name}"
2022-05-29 06:49:57 -05:00
...
2022-05-27 06:47:27 -05:00
>>> print(concat("Hello, ", "Bob"))
Hello, Bob
2022-05-30 15:22:31 -05:00
>>> print(concat(name="Bob", greeting="Hello, "))
2022-05-27 06:47:27 -05:00
Traceback (most recent call last):
2022-05-30 15:22:31 -05:00
print(concat(name="Bob", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
2022-05-27 06:47:27 -05:00
```
## Keyword Arguments
Keyword arguments are for parameters defined with a [default argument][default arguments].
Keyword arguments can optionally be called by their position.
Following is an example of keyword arguments being called by their keyword and by position:
```python
2022-05-30 15:22:31 -05:00
>>> def concat(greeting="Hello, ", name="you"):
... return f"{greeting}{name}"
2022-05-29 06:49:57 -05:00
...
2022-05-30 15:22:31 -05:00
>>> print(concat(name="Bob", greeting="Hello, "))
2022-05-27 06:47:27 -05:00
Hello, Bob
>>> print(concat("Hello, ", "Bob"))
Hello, Bob
2022-05-27 07:09:11 -05:00
>>> print(concat())
Hello, you
2022-05-27 06:47:27 -05:00
```
Arguments can be forced to be keyword--only through the use of the `*` operator.
Following is an example of keyword-only arguments:
```python
2022-05-30 15:22:31 -05:00
>>> def concat(*, greeting="Hello, ", name="you"):
... return f"{greeting}{name}"
2022-05-29 06:49:57 -05:00
...
2022-05-30 15:22:31 -05:00
>>> print(concat(name="Bob", greeting="Hello, "))
2022-05-27 06:47:27 -05:00
Hello, Bob
2022-05-27 07:09:11 -05:00
>>> print(concat())
Hello, you
2022-05-27 06:47:27 -05:00
>>> print(concat("Hello, ", "Bob"))
Traceback (most recent call last):
print(concat("Hello, ", "Bob"))
TypeError: concat() takes 0 positional arguments but 2 were given
```
## Positional or Keyword Arguments
Arguments can be positional or keyword if neither the `/` nor `*` operators are used in the parameter definitions.
Alternately, the positional-or-keyword arguemtns can be placed between the positional-only parameters on the left and the keyword-only parameters on the right.
2022-05-27 07:04:45 -05:00
Following is an example of positional-only, positional-or-keyword, and keyword-only arguments:
2022-05-27 06:47:27 -05:00
```python
2022-05-30 15:22:31 -05:00
>>> def concat(greeting, /, name="you", *, ending="."):
... return f"{greeting}{name}{ending}"
2022-05-29 06:49:57 -05:00
...
2022-05-30 15:22:31 -05:00
>>> print(concat("Hello, ", "Bob", ending="!"))
2022-05-27 06:47:27 -05:00
Hello, Bob!
2022-05-30 15:22:31 -05:00
>>> print(concat("Hello, ", name="Bob", ending="!"))
2022-05-27 06:47:27 -05:00
Hello, Bob!
2022-05-27 07:04:45 -05:00
>>> print(concat("Hello, "))
Hello, you.
2022-05-30 15:22:31 -05:00
>>> print(concat(greeting="Hello, ", name="Bob", ending="!"))
2022-05-27 06:47:27 -05:00
Traceback (most recent call last):
2022-05-30 15:22:31 -05:00
print(concat(greeting="Hello, ", name="Bob", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
2022-05-27 06:47:27 -05:00
```
## `*args`
2022-05-28 10:22:12 -05:00
Code examples will often use a function definition something like the following:
2022-05-27 09:50:51 -05:00
```python
2022-05-28 10:22:12 -05:00
def my_function(*args, **kwargs):
2022-05-27 09:50:51 -05:00
# code snipped
```
2022-05-28 10:22:12 -05:00
`*args` is a two-part name that represents an indefinite number of separate positional arguments, which is also known as a variadic argument.
2022-05-27 09:50:51 -05:00
`args` is the name of the group of arguments and could be any other name, such as `my_args` , `arguments` , etc.
The `*` is the operator which transforms the group of separate arguments into a [`tuple` ][tuple].
Since a tuple can be iterated, `args` can be passed to any other function which takes an iterable.
2022-05-28 10:22:12 -05:00
Although `*args` is commonly juxtaposed with `**kwargs` , it doesn't have to be.
2022-05-27 09:50:51 -05:00
Following is an example of an arbitrary amount of values being passed to a function between a positonal argument and a keyword argument:
```python
>>> def add(first, *args, last=0):
2022-05-29 06:49:57 -05:00
... return first + sum(args) + last
...
2022-05-27 09:50:51 -05:00
>>> print(add(1, 2, 3))
6
>>> print(add(1, 2, 3, last=4))
10
>>> print(add(*[1, 2, 3]))
6
```
Note that when an argument is already in an iterable, such as a tuple or list, it needs to be unpacked before being passed to a function that takes an arbitrary amount of separate arguments.
This is accomplished by `*` , which is the [unpacking operator][unpacking operator].
This unpacks the list into its separate elements which are then transformed by `*args` into a tuple.
Without unpacking the list passed into `add` , the program would error.
```python
>>>> def add(first, *args, last=0):
2022-05-29 06:49:57 -05:00
... return first + sum(args) + last
...
2022-05-27 09:50:51 -05:00
>>>> print(add([1, 2, 3]))
Traceback (most recent call last):
print(add([1, 2, 3]))
return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list
```
What happened is that the `*` in `*args` only unpacked the list into its separate elements, and it was done.
It did not reassemble the elements into a tuple.
2022-05-28 10:22:12 -05:00
## `**kwargs`
`**kwargs` is a two-part name that represents an indefinite number of separate [key-value pair][key-value] arguments.
`kwargs` is the name of the group of arguments and could be any other name, such as `my_args` , `arguments` , etc.
The `**` is the operator which transforms the group of separate arguments into a [`dictionary` ][dictionary].
Since a dictionary can be iterated, `kwargs` can be passed to any other function which takes an iterable.
Although `**kwargs` is commonly juxtaposed with `*args` , it doesn't have to be.
Following is an example of an arbitrary amount of key-value pairs being passed to a function:
```python
>>> def add(**kwargs):
2022-05-29 06:49:57 -05:00
... return sum(kwargs.values())
...
2022-05-28 10:22:12 -05:00
>>> print(add(one=1, two=2, three=3))
6
```
Note that the `values()` method is called to iterate on the dictionary values.
When iterating a dictionary the default is to iterate the keys.
Following is an example of an arbitrary amount of key-value pairs being passed to a function that iterates the keys:
```python
>>> def concat(**kwargs):
2022-05-29 06:49:57 -05:00
... return " ".join(kwargs)
...
2022-05-28 10:22:12 -05:00
>>> print(concat(one=1, two=2, three=3))
one two three
```
2022-05-27 06:47:27 -05:00
[default arguments]: https://www.geeksforgeeks.org/default-arguments-in-python/
2022-05-28 10:22:12 -05:00
[dictionary]: https://www.w3schools.com/python/python_dictionaries.asp
2022-05-27 06:47:27 -05:00
[function concept]: ../functions/about.md
2022-05-28 10:22:12 -05:00
[key-value]: https://www.pythontutorial.net/python-basics/python-dictionary/
2022-05-27 09:50:51 -05:00
[tuple]: https://www.w3schools.com/python/python_tuples.asp
[unpacking operator]: https://docs.python.org/3/tutorial/controlflow.html#unpacking -argument-lists