简体   繁体   English

参数如何在python装饰器中传递?

[英]How parameters pass in decorator of python?

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')

Above code parameterizes the decorator require with admin . 上面的代码使用admin参数化了装饰器require参数。 It seems to that function get_users passes to the parameter fn of wrapper . 函数get_users似乎传递给wrapper的参数fn However, how the get_users passes to the parameter fn ? 但是, get_users如何传递给参数fn

Here get_users() does not pass the the parameter fn 这里的get_users()没有传递参数fn

since the function get_users() is bound to the decorator require 由于函数get_users()已绑定到装饰器require

so the decorator is being called first, while your object/reference of get_users() is passed as an argument 因此首先调用装饰器,同时将您的get_users()对象/引用作为参数传递

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

When a function is defined inside another function, as happens here (in fact, there are two levels of this here), the inner function(s) get access to all the outer function's variables. 当在另一个函数中定义一个函数时(如此处所示)(实际上,这里有两个级别),内部函数可以访问所有外部函数的变量。 So it's not necessary to explicitly pass role or fn to the inner functions. 因此,没有必要将rolefn显式传递给内部函数。

Here's what's happening: 这是正在发生的事情:

  1. require() is called with role set to "admin" . 使用role设置为"admin"调用require()
  2. The require() function defines another function, wrapper() , which it returns. require()函数定义了另一个函数wrapper() ,该函数将返回该函数。 (As an aside, this function is not well named: it is the one that does the wrapping, not the one that actually serves as the wrapper. It should probably be called wrap() or decorate() .) (顺便说一句,此函数的名称并不好:它是进行包装的函数,而不是实际上充当包装器的函数。它可能应该称为wrap()decorate() 。)
  3. wrapper() is passed the function get_users() . wrapper()传递给函数get_users()
  4. wrapper() creates a new function, new_fn() , to be called in place of get_users() , and returns new_fn() . wrapper()创建一个新函数new_fn() ,以代替 get_users()进行调用,并返回new_fn() (Again, this is not the greatest name, it should probably be called wrapper() since it's the wrapper for the function being decorated.) (同样,这不是最伟大的名称,应该将其称为wrapper()因为它是装饰函数的包装器。)

Now, because of the aforementioned situation where inner functions have access to all the outer functions' variables (called a "closure"), new_fn() has access to both fn , which is the function it wrapped ( get_users() ) and also the role parameter that was originally passed to require() . 现在,由于上述情况,内部函数可以访问所有外部函数的变量(称为“关闭”),因此new_fn()可以访问fn ,这是它包装的函数( get_users() )和最初传递给require() role参数。 So it can check the user's role to see if the user is allowed to call that function, and then, if permitted, call the function and return the result, thereby serving as a substitute for get_users() with added functionality wrapped around the original function. 因此,它可以检查用户的角色,以查看是否允许该用户调用该函数,然后,如果允许,则调用该函数并返回结果,从而代替get_users() ,并在原始函数周围附加功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM