A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it. Python allows "nested" functions ie (a function within another function).
Python also allows you to return functions from other functions.
Let us say, your original function was called orig_func().
def orig_func(): #definition
print("Wheee!")
orig_func() #calling
Run this file, the orig_func() gets called and prints. "wheee".
Now, let us say, we want to modify this function, to do something before this calling this function and also something after this function.
So, we can do like this, either by option 1 or by option 2
--------option 1----------
def orig_func():
print("Wheee!")
print "do something before"
orig_func()
print "do something after"
Note that we have not modified the orig_func. Instead, we have made changes outside this function.
But may be, we want to make changes in a such a way that when orig_func is called, we are able to do something before and after calling the function. So, this is what we do.
--------option 2----------
def orig_func():
print "do something before"
print("Whee!")
print "do something after"
orig_func()
We have achieved our purpose. But at what cost? We had to modify the code of orig_func. This may not always be possible, specially, when someone else has written the function. Yet we want that when this function is called, it is modified in such a way, that something before and/or after can be done. Then the decorator helps us to do this, without modifying the code of orig_func. We create a decorator and can keep the same name as before. So, that if our function is called, it is transparently modified. We go through following steps.
a. Define the decorator. In the docorator,
1) write code to do something before orig_func, if you want to.
2) call the orig_func, to do its job.
3) write code to do something after orig_func, if you want to.
b. Create the decorator
c. Call the decorator.
Here is how we do it.
=============================================================
#-------- orig_func already given ----------
def orig_func():
print("Wheee!")
#------ write decorator ------------
def my_decorator(some_function):
def my_wrapper():
print "do something before" #do something before, if you want to
some_function()
print "do something after" #do something after, if you want to
return my_wrapper
#------ create decorator and call orig func --------
orig_func = my_decorator(orig_func) #create decorator, modify functioning
orig_func() #call modified orig_func
===============================================================
Note, that now orig_func has been modified through the decorator. So, now when you call orig_func(), it will run my_wrapper, which will do three steps, as already outlined.
Thus you have modified the functioning of orig_func, without modifying the code of orig_func, that is the purpose of the decorator.
@discombobulated
if you wanted to. Decorators are just functions. – Blender