简体   繁体   中英

How does the route decorator used in Flask work

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM