微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将多个参数传递给 Python 中的装饰器

如何解决将多个参数传递给 Python 中的装饰器

我正在尝试构建一个具有 RBAC 功能的 Flask 应用程序。为此,我编写了一个工作正常的装饰器,但它只能接受一个参数,意味着只有一个访问级别(例如 WRITE、READ、admin 等),但我想将多个参数传递给它。我试过传递一个列表,但它没有接受。我从未与装饰师合作过,因此需要帮助。谢谢。

def permission_required(permission):
  def decorator(f):
    @wraps(f)
      def decorated_function(*args,**kwargs):
        if not current_user.can(permission):
          abort(403)
        return f(*args,**kwargs)
     return decorated_function
   return decorator

def admin_required(f):
  return permission_required(Permission.ADMIN)(f)

我是这样传递的:

@role_needed(Permission.VIEW),但我想要这个 @role_needed(Permission.VIEW,Permission.WRITE)

我的权限类是这样的:

class Permission:
  VIEW = 'Vew'
  WRITE = 'Write'
  ADMIN = 'admin'

解决方法

首先,我建议你看一些关于装饰器的教程,它们很酷,如果你想使用 Flask,你肯定需要了解基础知识。我个人非常喜欢this RealPython tutorial

其次,您有两种解决方案:默认第二个参数或参数打包。

def permission_required(permission1,permission2=None):
...

def permission_required(*perms):
...

我个人更喜欢第二种选择。 示例:

def permission_required(*perms):
  def decorator(f):
    @wraps(f)
      def decorated_function(*args,**kwargs):
        for perm in perms:
            if not current_user.can(perm):
              abort(403)
        return f(*args,**kwargs)
     return decorated_function
   return decorator
,

我认为你忽略了装饰器只是普通函数的一点,在参数中采用一个函数和另一个函数,后者是通过设计原始函数的包装器。在您的情况下, entriesList2 = [i.get() for i in entriesList] 是一个装饰器工厂,可用于根据输入参数专门化一个装饰器。所以你需要做的就是允许将任意数量的参数传递给你的装饰器工厂:

permission_required

可以按预期调用:

def role_needed(*permissions):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args,**kwargs):
            nonlocal permissions  # Just to make sure `permission` is available in this scope
            # Implement here how to deal with permissions
            return f(*args,**kwargs)
        return decorated_function
    return decorator

在函数中,@role_needed(Permission.VIEW,Permission.WRITE,...) 会将输入 permissions 存储为 Python Permission 对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。