参数如何在python的decorator中传递?

时间:2013-10-24 15:31:04

标签: python closures decorator

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

2 个答案:

答案 0 :(得分:1)

此处get_users()未传递参数fn

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

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

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

答案 1 :(得分:1)

当一个函数在另一个函数中定义时,就像这里发生的那样(事实上,这里有两个级别),内部函数可以访问所有外部函数的变量。因此,没有必要明确地将rolefn传递给内部函数。

以下是发生的事情:

    调用
  1. require()时,role设置为"admin"
  2. require()函数定义了它返回的另一个函数wrapper()。 (顺便说一句,这个函数没有很好地命名:它是执行包装的那个,而不是实际用作包装器的那个。它应该被称为wrap()decorate()。)< / LI>
  3. wrapper()传递了函数get_users()
  4. wrapper()创建一个名为的新功能new_fn(),代替 get_users(),然后返回new_fn()。 (同样,这不是最好的名字,它应该被称为wrapper(),因为它是被装饰函数的包装器。)
  5. 现在,由于上述情况,内部函数可以访问所有外部函数的变量(称为“闭包”),new_fn()可以同时访问fn,这是函数包装(get_users())以及最初传递给role的{​​{1}}参数。因此,它可以检查用户的角色,以查看是否允许用户调用该函数,然后,如果允许,调用该函数并返回结果,从而替代require()并附加功能。原始功能。