2013-10-24 46 views
1
def require(role): 
    def wrapper(fn): 
     def new_fn(*args, **kwargs): 
      if not role in kwargs.get('roles', []): 
       print("%s not in %s" % (role, kwargs.get('roles', []))) 
       raise Exception("Unauthorized") 
      return fn(*args, **kwargs) 
     return new_fn 
    return wrapper 

@require('admin') 
def get_users(**kwargs): 
    return ('Alice', 'Bob') 

上面的代碼參數化裝飾器requireadmin。看起來功能get_users傳遞給wrapper的參數fn。但是,get_users如何傳遞給參數fn參數如何通過python的裝飾器傳遞?

+0

你的意思是你想給'get_users()'訪問'role'的值? –

回答

1

當一個函數DEFI在這裏發生的另一個函數(實際上,這裏有兩層),內部函數可以訪問所有外部函數的變量。因此沒有必要明確地將rolefn傳遞給內部函數。

這裏發生的事情:

  1. require()被稱爲與role設置爲"admin"
  2. require()函數定義了它返回的另一個函數wrapper()。 (順便說一句,這個功能沒有很好地命名爲:這是一個沒有包裝,沒有實際作爲包裹材料之一,它或許應該被稱爲wrap()decorate()。)
  3. wrapper()傳遞函數get_users()
  4. wrapper()創建了一個新的功能,new_fn(),代替get_users()被稱爲,並返回new_fn()。 (再次,這是不是最大的名字,它或許應該被稱爲wrapper()因爲它的功能被裝飾的包裝。)

現在,由於上述情況的內部函數必須所有的外部功能接入'變量(稱爲「封閉」),new_fn()可以訪問fn,這是它包裝的功能(get_users())以及最初傳遞給require()role參數。因此它可以檢查用戶的角色,看看是否允許用戶調用該函數,然後在允許的情況下調用該函數並返回結果,從而替代get_users(),並在原始函數中添加了功能。

+0

我知道沒有必要明確地將角色或fn傳遞給內部函數。我很困惑,沒有明確意義的fn傳遞給內部函數。 – liu

+0

我真的不知道你在問什麼。 – kindall