We have seen usage of @route()
decorator in Flask and they really make routing easy and backend development fast. But how do they really work? How do we implement one?
We wrote a decorator and added print("hello", f.__name__)
to see if it really gets printed. If you are still not familiar how to write decorators, you can find a separate blog here.
def route(path):
def _route(f):
print("hello", f.__name__)
return f
return _route
@route("/")
def index():
pass
if __name__ == '__main__':
pass
As you can see, we did not call any function. Not even index()
function. And you can find that there is a console output.
hello index
This proves that decorators are called during object initialization.
Let's add another decorator and check the output.
@route("/")
@route("/index")
def index():
pass
After running the code, we will see the same output.
hello index
hello index
From here, we can easily register the paths.
ROUTE_MAP = {}
def route(path):
def _route(f):
ROUTE_MAP[path] = f
return f
return _route
@route("/")
@route("/index")
def index():
print("index is called")
if __name__ == '__main__':
print(ROUTE_MAP) # {'/index': <function index at 0x103f89cb0>, '/': <function index at 0x103f89cb0>}
And calling the index
function from the route is simply done using ROUTE_MAP
.
if __name__ == '__main__':
ROUTE_MAP["/"]() # index is called
ROUTE_MAP["/index"]() # index is called
Conclusion
Decorators are always called during object initialization.
Decorators are alway called during object initialization and that's a fact. It makes decorators very versatile and very dangerous. 3rd-party decorators might do something bad during initialization so be careful on using one.