Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将两个python装饰器组合成一个_Python_Python 3.x_Decorator_Bottle_Python Decorators - Fatal编程技术网

将两个python装饰器组合成一个

将两个python装饰器组合成一个,python,python-3.x,decorator,bottle,python-decorators,Python,Python 3.x,Decorator,Bottle,Python Decorators,这里有两个我想组合的装饰器,因为它们非常相似,区别在于如何处理未经身份验证的用户。我更喜欢有一个单独的装饰,我可以调用一个参数 #路由的身份验证装饰器 #如果未通过身份验证,将重定向到登录页面 def要求重新验证(fn): def装饰器(**kwargs): #用户是否已登录? 如果request.session中的“用户”: 返回fn(**kwargs) #否,重定向到登录页面 其他: 重定向('/login?url={0}{1}'。格式(request.path,(“?”+request.q

这里有两个我想组合的装饰器,因为它们非常相似,区别在于如何处理未经身份验证的用户。我更喜欢有一个单独的装饰,我可以调用一个参数

#路由的身份验证装饰器
#如果未通过身份验证,将重定向到登录页面
def要求重新验证(fn):
def装饰器(**kwargs):
#用户是否已登录?
如果request.session中的“用户”:
返回fn(**kwargs)
#否,重定向到登录页面
其他:
重定向('/login?url={0}{1}'。格式(request.path,(“?”+request.query\u字符串如果request.query\u字符串为其他“”))
返回装饰器
#路由的身份验证装饰器
#如果未经验证,将返回错误消息(JSON)
def requireAuthenticationJSON(fn):
def装饰器(**kwargs):
#用户是否已登录?
如果request.session中的“用户”:
返回fn(**kwargs)
#否,返回错误
其他:
返回{
“例外情况”:“未授权”,
“错误”:“您未经授权,请登录”
}
返回装饰器
目前我正在为特定的路线使用这些装饰器,例如

@get(“/day/”)
@helpers.requireAuthentication
定义日期():
...
@获取('/night/'))
@helpers.requireAuthenticationJSON
def night():
...
我更喜欢这个:

@get(“/day/”)
@helpers.requireAuthentication()文件
定义日期():
...
@获取('/night/'))
@helpers.requireAuthentication(json=True)
def night():
...

我正在使用瓶子框架使用Python3.3。有可能做我想做的吗?如何操作?

只需添加另一个包装器即可捕获
json
参数:

def requireAuthentication(json=False):
    def decorator(fn):
        def wrapper(**kwargs):
            # Is user logged on?
            if "user" in request.session:
                return fn(**kwargs)

            # No, return error
            if json:
                return {
                    "exception": "NotAuthorized",
                    "error" : "You are not authorized, please log on"
                }
            redirect('/login?url={0}{1}'.format(request.path, ("?" + request.query_string if request.query_string else '')))
        return wrapper
    return decorator
我已将原始的
requireAuthentication
函数重命名为
decorator
(因为该函数就是这样做的,它修饰了
fn
),并将旧的
decorator
重命名为
包装器
,这是通常的惯例


@
后面放置的任何内容都是一个表达式,首先求值以找到实际的decorator函数
@helpers.requireAuthentication()
表示您要调用
requireAuthentication
,然后它的返回值被用作
@
行应用的函数的实际装饰器。

您可以为这两个装饰器创建包装器:

def requireAuthentication(json=False):
    if json:
        return helpers.requireAuthenticationJSON
    else:
        return helpers.requireAuthentication

import functools
# Authentication decorator for routes
# Will redirect to the login page if not authenticated
def requireAuthentication(json=False):
    def requireAuthentication(fn):
        @functools.wraps(fn)
        def decorator(*args, **kwargs):
            # Is user logged on?
            if "user" in request.session:
                return fn(*args, **kwargs)
            if json:
                 return {
                "exception": "NotAuthorized",
                "error" : "You are not authorized, please log on"
            }
            return redirect('/login?url={0}{1}'.format(request.path, 
                                                       ("?" + request.query_string if request.query_string else '')))
        return decorator
    return requireAuthentication