2013-10-24 38 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