I'm familiar with the basics of Python's decorators. However I don't understand how this specific decorator, as used for Flask routes, works.
Here is a code snippet from the Flask website:
from flask import Flask, escape, request
app = Flask(__name__)
@app.route('/')
def hello():
name = request.args.get("name", "World")
return f'Hello, {escape(name)}!'
.route('/')
is the part which confuses me. The way I've seen decorators being used is that the decorator annoation is usually a function, which takes one argument, which is the decorated function itself, which can then be executed inside the decorator. But this seems to be different here.
Thank you.
Update: Thanks for the hint about self
in my second code snippet. Being new to Python I totally forgot that something
's first argument has to be self
. At second glance, I don't think that the example helps to clarify the question and have therefore removed it.
It sounds like you have a couple misconceptions that we can hopefully clear up. Firstly, a decorator is just a term ( and some language "sugar", the @decorator
syntax ) for a callable that accepts a callable and returns another callable. This callable can be a function ( eg, def foo(func)
) or a method ( eg, obj.method(func)
) -- it just needs to be something that accepts a callable and returns one.
In the case of Flask's @app.route
decorator, you're passing your hello
function to an object's ( the flask.Flask
object I believe ) route
method. In turn it adds your function and its associated configuration to its own "memory" for routing once the Flask application is told to begin serving requests.
Secondly, your example has def something(arg1, arg2):
-- the first argument passed to an object's method when called is the object instance, usually called self
The Primer on Python Decorators article might be a good place to get started to read up on how/why they work the way they do.
A decorator is simply a function that accepts a function as a parameter and returns another function. A decorator that accepts arguments (like flask's route
decorator) must return a function that can be used as a simple decorator.
For example, we could write that route
decorator like this:
routes = {}
def route(path):
def inner(func):
global routes
routes[path] = func
return func
return inner
Calling route('/')
returns a function that takes a function as an argument, which updates the global routes
variable using the value of path
passed to the outer function and the func
value received by the inner function.
If we use that on a couple of functions:
@route('/')
def func1():
...
@route('/example')
def func2():
...
Then we can inspect the routes
variable and see that it now maps paths to the appropriate functions. Running:
print(routes)
Produces something like:
{'/': <function func1 at 0x7f0c4aeac050>, '/example': <function func2 at 0x7f0c4aeb1e60>}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.