**kwargs 在此包装函数中有什么好处?

What is the benefit of **kwargs in this wrapper function?

以下函数是作为 Web 开发简介中示例的一部分提供的:

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('login'))
        return view(**kwargs)
    return wrapped_view

调用它的函数没有参数:

@app.route('/topsecret')
@login_required
def top_secret():
    return f'<H1>Really top secret stuff!</H1>'

那么这里有一个 **kwargs 参数有什么意义呢?如果未来的函数使用包装器并有参数,是否只是为了让函数更灵活?

以下是完整代码供参考:

from flask import Flask, url_for, request, redirect, make_response, session, \
     render_template, g
import functools
import secrets

app = Flask(__name__)
app.secret_key = secrets.token_urlsafe(32)

@app.before_request
def user_logged_in():
    user_id = session.get('username')
    if user_id == None:
        g.user = None
    else:
        g.user='set'
        
def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('login'))
        return view(**kwargs)
    return wrapped_view

@app.route('/')
def index():
    if 'username' in session:
        return f'Logged in as {session["username"]}'
    return 'You are not logged in.'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
        '''

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

@app.route('/topsecret')
@login_required
def top_secret():
    return f'<H1>Really top secret stuff!</H1>'

@app.route('/notsosecret')
def notsosecret():
    return f'<H1>Not so important stuff</H1>'

So what is the point in there being a **kwargs parameter here? Is it simply to allow the function to be more flexible if future functions use the wrapper and have parameters?

是的。 Flask 处理程序可以通过路由参数接收关键字参数(并且 关键字参数)。如果您希望 login_required 使用此类处理程序,则需要转发参数。

考虑:

@app.route('/topsecret/<key>')
@login_required
def top_secret(key="007"):
    return f'<H1>Really top secret stuff for {key}!</H1>'