Parameters and Arguments
- Here's a demo of a function definitions and call.
(comments tell you where parameters are used, and where arguments are used)
1def twice(num): # num is a parameter
2 print(2 * num)
3
4twice(5) # 5 is an argument
5x = 3
6twice(x) # x is an argument
Positional and Keyword Arguments
- This is a function with 2 positional parameters.
The function is called
- first using positional arguments
- then using keyword arguments
1def sub_nums(a, b): # a and b are formal parameters
2 print(a-b)
3
4sub_nums(5, 3) # 5 and 3 are positional arguments
5sub_nums(b=4, a=8) # b=4 and a=8 are keyword arguments
Default argument values
- You can set a default value for an argument
- If you do that, there are 2 options:
- either you set an argument in the call
- or you don't set an argument, and the default value will be used.
- Example:
1def show_three(a, b=2, c=3):
2 print(a, b, c)
3
4show_three(8, 8, 8) # will print 8, 8, 8
5show_three(8, 8) # will print 8, 8, 3
6show_three(8) # will print 8, 2, 3
7show_three(8, c=4) # will print 8, 2, 4
8show_three(8, c=11, b=10) # will print 8, 10, 11
9
10#Bad options:
11# show_three()
12# show_three(b=4)
Mixing Positional and Keyword arguments
- If you mix positional and keyword arguments, then positional arguments must appear beforehand:
1def add_three(a, b, c):
2 print(a+b+c)
3
4# Good options:
5add_three(5, 6, c=7)
6add_three(5, b=6, c=7)
7add_three(5, c=6, b=7)
8add_three(c=5, b=6, a=7)
9# Bad options:
10# add_three(a=5, 6, 7)
11# add_three(a=5, b=6, 7)
12# add_three(2, 3, b=4)
Using * to get a tuple
- You can use an asterisk to get several arguments packed as a tuple:
1def params(a, b, *more):
2 print(a)
3 print(b)
4 print(more)
5 print(type(more))
6
7params(1, 2, 3, 4, 5)
- When run, this is what you'll get:
11
22
3(3, 4, 5)
4<class 'tuple'>
- Note that you can only use this once, after some positional arguments
Using ** to get a dictionary
- You can have keyword arguments packed for you as a dictionary
- You can use this once, at the end
- Example:
1def params_dict(a, b, **others):
2 print(a, b, others)
3 print(type(others))
4
5params_dict(1, 2, f=3, e=4, d=5, c=6)
6params_dict(1, b=2, f=3, e=4, d=5, c=6)
7
8# Bad Option:
9# params_dict(1, 2, 3, e=4, d=5, c=6) # too many positionals
- This is what you'll get when you run it:
11 2 {'f': 3, 'e': 4, 'd': 5, 'c': 6}
2<class 'dict'>
31 2 {'f': 3, 'e': 4, 'd': 5, 'c': 6}
4<class 'dict'>
Big all-included Example
- This is how it looks if we use everything:
1def params_all(a, b, *some_positionals, **dict_others):
2 print(a, b, some_positionals, dict_others)
3
4params_all(1, 2, 3, 4, 5, d1=6, d2=7, d3=8)
- An this is the result of this code:
11 2 (3, 4, 5) {'d1': 6, 'd2': 7, 'd3': 8}
The * Stopper
- When you see a * sign placed as one of the parameters (without a parameter name) it means that after it - only keyword arguments are allowed.
- Example:
1def params_all(a, b, *, c, d):
2 print(a, b, c, d)
3
4params_all(1, 2, c=3, d=4)
5params_all(1, 2, d=3, c=4)
6
7# params_all(1, 2, 3, 4)
- In this example, you can send values to a and b by using positional arguments, but you cannot do that to the parameters after the * (c and d)