簡體   English   中英

將多個 arguments 傳遞給 Python 中的裝飾器

[英]Pass multiple arguments to a decorator in Python

我正在嘗試構建一個具有 RBAC 功能的 flask 應用程序。 為此,我編寫了一個運行良好的裝飾器,但它只能接受一個參數,意味着只有一個訪問級別(例如 WRITE、READ、admin 等),但我想將多個 arguments 傳遞給它。 我試過傳遞一個列表,但它沒有接受它。 我從未與裝飾師合作過,因此需要幫助。 謝謝。

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 是這樣的:

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

首先,我建議你看一些關於裝飾器的教程,它們非常酷,如果你想使用 flask,你肯定需要了解基礎知識。 我個人非常喜歡這個 RealPython 教程

其次,您有兩種解決方案:默認的第二個參數或參數打包。

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

我認為你錯過了裝飾器只是常用功能的觀點,在參數中使用 function 和另一個,后者是設計一個圍繞原始函數的包裝器。 在您的情況下, permission_required是一個裝飾器工廠,可用於根據輸入 arguments 專門化裝飾器。 因此,您需要做的就是允許將任意數量的 arguments 傳遞給您的裝飾器工廠:

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, ...)

在 function 中, permissions將輸入Permission存儲為 Python tuple object。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM