装饰设置的功能属性(decorator to set attributes of function)

2019-08-19 07:00发布

我想不同的功能,只有当登录的用户具有所需的权限级别执行。

为了使我的生活变得更加复杂只是我想用装饰。 下面我attempy设置属性permission的“装饰”功能-如下图所示。

def permission(permission_required):
    def wrapper(func):
        def inner(*args, **kwargs):
            setattr(func, 'permission_required', permission_required)
            return func(*args, **kwargs)
        return inner
    return wrapper

@permission('user')
def do_x(arg1, arg2):

    ...

@permission('admin')
def do_y(arg1, arg2):
    ...

但是,当我这样做:

fn = do_x
if logged_in_user.access_level == fn.permission_required:
    ...

我得到一个错误'function' object has no attribute 'permission_required'

我在想什么?

Answer 1:

您设置在内部(包装)功能的属性。 你并不需要一个包装函数

def permission(permission_required):
    def decorator(func):
        func.permission_required = permission_required
        return func
    return decorator

你的装饰需要返回的东西 ,会取代原来的功能。 原函数本身(与添加的属性)会做得很好的,因为你唯一想做的就是添加属性给它。

如果您仍需要一个包装,然后设置在包装功能的属性改为:

def permission(permission_required):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # only use a wrapper if you need extra code to be run here
            return func(*args, **kwargs)
        wrapper.permission_required = permission_required
        return wrapper
    return decorator

毕竟,要更换由装饰返回的包装纸包装的功能,所以这就是你要寻找的该属性的对象。



Answer 2:

你的装饰应返回功能,可以取代do_xdo_y ,不返回执行结果do_xdo_y可以modity你装饰如下:

def permission(permission_required):
    def wrapper(func):
        def inner():
            setattr(func, 'permission_required', permission_required)
            return func
        return inner()
    return wrapper

当然,你有另一种简单的解决方案:

def permission(permission_required):
    def wrapper(func):
        setattr(func, 'permission_required', permission_required)
        return func
    return wrapper


文章来源: decorator to set attributes of function