• python装饰器系列(五)


    带参数的装饰器的应用:

    比如有一个函数,只有在对有许可权限的用户开放,执行此函数的用户没有在认证列表里的,就不会执行这个函数。这个该如何实现呢?如下:

     1 def check(allow_users):
     2     def inner_check(fn):
     3         def wrap(username,*args,**kwargs):
     4             '''This is wrap'''
     5             if username in allow_users:
     6                 return fn(username,*args,**kwargs)
     7             return "You are illegal users"
     8         return wrap
     9     return inner_check
    10  
    11 
    12 @check(['zhaochj','zcj'])
    13 def private(username):
    14     '''The authentication'''
    15     return "You are legitimate users"
    1 private('zhaochj')
    2 'You are legitimate users'
    1 private('tom')
    2 'You are illegal users'

    这样就可以对调用函数进行身份验证

    python中一个函数有一些属性是函数本身具有的,比如__name__属性是查看函数名称,如果一个函数被装饰器装饰过后,这个函数的这些属性会发生怎样的变化呢?

    以上边的check装饰器和private函数为例子,如下:

    1 private.__name__
    2 'wrap'

    private函数的名称是wrap了,这是怎么回事?上边已经说过,这里的private函数被装饰器装饰后它已不再是原来的private函数,private这个函数名称会被指向到wrap这个函数对象,那当然用上边的private.__name__查看函数的属性就会是wrap函数的属性。

    那怎样来修正呢?可以这样做,如下:

     1 def check_1(allow_users):
     2     def inner_check(fn):
     3         def wrap(username,*args,**kwargs):
     4             '''This is wrap'''
     5             if username in allow_users:
     6                 return fn(username,*args,**kwargs)
     7             return "You are illegal users"
     8         wrap.__name__ = fn.__name__
    10         return wrap
    11     return inner_check
    12  
    13 @check_1(['zhaochj','zcj'])
    14 def private_1(username):
    15     '''The authentication'''
    16     return "You are legitimate users"
    1 private_1.__name__
    2 'private_1'

    通过在装饰器把__name__重新赋值后就能更正这个问题,但对一个函数来说像__name__这样类似的属性有许多,如果都是这样手工来修正显然是不现实的,所以python提供了一个wraps装饰器来自动修正这个问题,wrapsfunctools这个包中,所以可以这样来修正这个问题,如下:

     1 import functools
     2  
     3 def check_1(allow_users):
     4     def inner_check(fn):
     5         @functools.wraps(fn)
     6         def wrap(username,*args,**kwargs):
     7             '''This is wrap'''
     8             if username in allow_users:
     9                 return fn(username,*args,**kwargs)
    10             return "You are illegal users"
    11         return wrap
    12     return inner_check
    13  
    14 @check_1(['zhaochj','zcj'])
    15 def private_1(username):
    16     '''The authentication'''
    17     return "You are legitimate users"
    1 private_1.__name__
    2 'private_1'

    @functools.wraps(fn)这个装饰器相当于执行了wrap.__name__ = fn.__name__这样的操作

  • 相关阅读:
    【文本处理命令】之find搜索命令
    【文本处理命令】之grep搜索命令详解
    【VM配置】配置主机名称、网卡和yum源配置
    【Linux命令】安装命令(yum,rpm)
    【Linux命令】文件目录管理命令7个(touch、mkdir、cp、mv、rm、dd、file)
    【Linux命令】文本文件编辑命令10个(cat、more、less、head、tail、tr、wc、stat、cut、diff)
    Redis系列---redis简介01
    redis中 Could not get a resource from the pool 异常解决
    Nginx配置Tomcat8反向代理出现 java.lang.IllegalArgumentException: The character [_] is never valid in a domain name.
    FtpClient上传文件速度非常慢,而且大小为0,上传失败
  • 原文地址:https://www.cnblogs.com/tianshug/p/10921944.html
Copyright © 2020-2023  润新知