Function Decorator Basics
Function decorators are used in many python packages and libraries.
Often, you see the @ sign in code before you learn what it is, so you get back to read about decorators.
We'll use a simple example to demonstrate the use of decorators.
What do we try to achieve
- Suppose you have a simple, 2 params function like the following:
1def add_nums(a,b):
2 return a+b
- This is a simple one, but it has no defaults, so if you try to call it, say, with just one parameter, it would fail:
1>>> def add_nums(a,b):
2... return a+b
3...
4>>>
5>>> add_nums(5)
6Traceback (most recent call last):
7 File "<stdin>", line 1, in <module>
8TypeError: add_nums() missing 1 required positional argument: 'b'
9>>>
- The "magic" we want to achieve, is that we "decorate" this function, so that it'll "change" the function so it gets defaults for its parameters:
1>>> from add_defaults_decorator import add_defaults
2>>>
3>>> @add_defaults
4... def add_nums(a, b):
5... return a+b
6...
7>>>
8>>> add_nums(3, 4)
97
10>>> add_nums(4)
114
12>>> add_nums()
130
14>>>
Decorator magic WITHOUT the decorator sign
This is what we'd do to create our function decorator:
- We write the decorator function (add_defaults in our case)
- This function accepts a two_params_func as a parameter, and returns ANOTHER function, one that:
- has default values
- calling the original 2 params function
1def add_defaults(two_params_func):
2 def two_params_with_defaults_func(a=0, b=0):
3 return two_params_func(a,b)
4 return two_params_with_defaults_func
- ..so now, we can create our 2 params (default-less) function, then use add_defaults to replace it with a better version:
1def add_nums(a,b):
2 return a+b
3
4add_nums = add_defaults(add_nums)
- Now, the name add_nums stays, but this is another function altogether.
Now, with the @ sign
- Same thing:
1def add_defaults(two_params_func):
2 def two_params_with_defaults_func(a=0, b=0):
3 return two_params_func(a,b)
4 return two_params_with_defaults_func
5
6# The following decorator actually calls add_defaults, just the same:
7
8@add_defaults
9def add_nums(a,b):
10 return a+b
- Not that we do not call the decorator function itslef. We write a reference to it next to the @ sign, and let python call it.