Python decorator in a flask

Here is my example:

from flask import Flask

app = Flask(__name__)
def add1(f):
    def inner(*args, **kwargs):
        return str(f(*args, **kwargs))+'1'
    return inner


@app.route('/')
@add1
def hello1():
    return "hello1";

@app.route('/hello2')
@add1
def hello2():
    return "hello2";


if(__name__ =='__main__'):
    app.run()

When I run 127.0.0.1/1000, I expect to get "hello11", but I get "hello21", why?

+5
source share
1 answer

The problem is that Flask keeps track of functions by name, but because the functions passed to app.route(path)are called inner, the second ( hello2) overwrites the first. To fix this, you will need the name of the function inner, which will be changed to the name of the function that it decorates. You can change the decorator to

def add1(f):
    def inner(*args, **kwargs):
        return str(f(*args, **kwargs))+'1'
    inner.__name__ = f.__name__
    return inner

which will work, but not as elegant as the standard library solution,

from functools import wraps

def add1(f):
    @wraps(f)
    def inner(*args, **kwargs):
        return str(f(*args, **kwargs))+'1'
    return inner

The decorator wrapsnot only captures the name, but also the docstring, file, and attribute dictionary.

+13
source

All Articles