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')
以上代码使用require
将装饰器admin
参数化。似乎函数get_users
传递给fn
的参数wrapper
。但是,get_users
如何传递给参数fn
?
答案 0 :(得分:1)
此处get_users()
未传递参数fn
因为函数get_users()
绑定到装饰器require
所以首先调用装饰器,而get_users()
的对象/引用作为参数传递
答案 1 :(得分:1)
当一个函数在另一个函数中定义时,就像这里发生的那样(事实上,这里有两个级别),内部函数可以访问所有外部函数的变量。因此,没有必要明确地将role
或fn
传递给内部函数。
以下是发生的事情:
require()
时,role
设置为"admin"
。require()
函数定义了它返回的另一个函数wrapper()
。 (顺便说一句,这个函数没有很好地命名:它是执行包装的那个,而不是实际用作包装器的那个。它应该被称为wrap()
或decorate()
。)< / LI>
wrapper()
传递了函数get_users()
。wrapper()
创建一个名为的新功能new_fn()
,代替 get_users()
,然后返回new_fn()
。 (同样,这不是最好的名字,它应该被称为wrapper()
,因为它是被装饰函数的包装器。)现在,由于上述情况,内部函数可以访问所有外部函数的变量(称为“闭包”),new_fn()
可以同时访问fn
,这是函数包装(get_users()
)以及最初传递给role
的{{1}}参数。因此,它可以检查用户的角色,以查看是否允许用户调用该函数,然后,如果允许,调用该函数并返回结果,从而替代require()
并附加功能。原始功能。