如何使多个@wraps更小?

use*_*153 1 python functools

我对 python 还不够了解,无法自己解决这个问题,所以这就是我想在这里尝试的原因。有没有办法让这些几乎相同的@wraps函数占用更少的空间?我总共有 5 个这样的东西,100 行 5 次同样的东西听起来很浪费。我最初在某个网站上找到过这个,但现在似乎找不到了。

功能:

def a_required(func):
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if request.method in EXEMPT_METHODS:
            return func(*args, **kwargs)
        elif current_app.config.get('LOGIN_DISABLED'):
            return func(*args, **kwargs)
        elif not current_user.is_authenticated or not current_user["Keys"]["A"]:
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view

def b_required(func):
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if request.method in EXEMPT_METHODS:
            return func(*args, **kwargs)
        elif current_app.config.get('LOGIN_DISABLED'):
            return func(*args, **kwargs)
        elif not current_user.is_authenticated or not current_user["Keys"]["B"]:
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view
Run Code Online (Sandbox Code Playgroud)

这是一个 Flask 网站,其页面只有拥有正确权限的用户才能访问。

Cam*_*ell 6

您可以编写一个返回装饰器的函数,并像这样调用它:

def required(req):
    def wrapper(func):
        @wraps(func)
        def decorated_view(*args, **kwargs):
            # put your decorated_view code here
            #  swapping out the hard coded `current_user["Keys"]["B"]`
            #  for `current_user["Keys"][req]`

            print("executing decorator with", req)
            return func(*args, **kwargs)
        return decorated_view
    return wrapper

@required("B")
def foo():
    print("inside foo function")
    
@required("A")
def bar():
    print("inside bar function")
Run Code Online (Sandbox Code Playgroud)

然后执行这些函数如下所示:

>>> foo()
executing decorator with B
inside foo function

>>> bar()
executing decorator with A
inside bar function
Run Code Online (Sandbox Code Playgroud)

该函数required返回一个动态装饰器,该装饰器根据req我们传递给它的值更改其行为。这样,函数就可以根据我们调用的方式decorated_view访问适当的值。reqrequired(...)