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传递给 的参数fnwrapper但是,如何get_users传递给参数fn

4

2 回答 2

1

这里get_users()不传参数fn

因为函数get_users()绑定到装饰器require

所以首先调用装饰器,而您的对象/引用get_users()作为参数传递

有关详细信息,请参阅https://wiki.python.org/moin/PythonDecorators

于 2013-10-24T15:41:06.070 回答
1

当一个函数在另一个函数内部定义时,就像这里发生的那样(实际上,这里有两个层次的 this),内部函数可以访问所有外部函数的变量。所以没有必要显式地传递role或传递fn给内部函数。

这是正在发生的事情:

  1. require()调用时role设置为"admin"
  2. require()函数定义了另一个函数,wrapper()它返回。(顺便说一句,这个函数的名字不是很好:它是进行包装的那个,而不是实际用作包装的那个。它可能应该被称为wrap()or decorate()。)
  3. wrapper()传递函数get_users()
  4. wrapper()创建一个新函数 ,new_fn()代替 get_users(), 并返回new_fn(). (同样,这不是最好的名字,它可能应该被调用wrapper(),因为它是被装饰的函数的包装器。)

现在,由于前面提到的情况,内部函数可以访问所有外部函数的变量(称为“闭包”),new_fn()可以访问两者fn,即它包装的函数(get_users())和role最初传递给的参数require()。因此它可以检查用户的角色以查看是否允许用户调用该函数,然后,如果允许,则调用该函数并返回结果,从而充当get_users()围绕原始函数的附加功能的替代品。

于 2013-10-24T15:41:54.243 回答