伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

【py3】10分钟彻底搞清楚:装饰器

来源:本站原创 浏览:92次 时间:2022-12-02

本文将从以下几点讨论python3中的装饰器:

  • 闭包传递函数引用

  • 什么是装饰器

  • @注解完成装饰器

  • 装饰器的装饰time

  • 装饰带参数的函数

  • 装饰带返回值的函数

  • 装饰器带参数

  • 多个装饰器

  • 保留被装饰函数的__name__属性


在python中函数,对象统统都可以赋值给变量,如果把一个函数赋值给一个变量,那么通过这个变量就可以调用函数。有关闭包可查阅小编涂鸦之作—【python3闭包】。这里我们将函数直接传到闭包里完成调用。

(func):    ():        func()():    ()

什么是装饰器

通常有些函数功能是非业务性质的(权限、日志、事务等),我们希望将这些函数功能植入到业务函数处理中,又不想破坏业务函数的定义,这种在运行期动态增强功能的方式就是装饰器。上面的示例中,显然已经拿到了目标函数的引用,我们就可以在目标函数执行前、执行后进行增强。这里我们在函数执行前后打印日志。

(func):    ():        ()        func()        ()

注解完成装饰器

结合示例1和示例2我们就完成了装饰器的使用,没有改变目标函数定义,增强了目标函数功能。但是在调用上略显吃力,我们可以直接使用@+装饰器函数置于目标函数上,完成装饰操作。

(func):    ():        ()        func()        ()

装饰器的装饰time

python3是解释型编程语言,从上至下依次解释执行。所以在目标函数执行前装饰器已经装饰好了。下面我们并没有调用任何函数,执行时装饰器已生效。

()        func()        ()

装饰带参数的函数

很多时候目标函数都是带参数的,这里使用标准的不定长传参,注意在调用目标函数时,元组参数args要加*,关键字参数kwargs加**,用于拆包,否则目标函数接收到的是一个元组和字典。函数定义时,*args和**kwargs用来声明将元组参数接收到args中,将关键字参数接收到kwargs中。

time(func):    ()    (*args**kwargs):        start = time.time()        (% start)        func(*args**kwargs)        end = time.time()        (% (end(end - start)))    wrap(name*args**kwargs):    time.sleep()    (nameargskwargs)__name__ == :

装饰带返回值的函数

目标函数有返回值的情况很容易处理,经过上面的示例,我们知道装饰器就是将目标函数作为变量传入,然后由装饰器触发目标函数。带有返回值的函数,只需由装饰器内部接收返回值,并返回即可。

(func):    (*args**kwargs):        func(*args**kwargs)    wrap():__name__ == :

装饰器带参数

很多时候装饰器自身也需要参数支持,比如记录日志我们希望知道是哪个业务模块的,或日志的级别等。上面的示例装饰器用来接收函数变量名了,装饰器内部的嵌套函数用来接收目标函数参数了,所以装饰器想要接收参数只能再来一层嵌套函数了。

(name):    (func):        (*args
(% name)            func(*args
            (% name)        logging    wrap()(num):

多个装饰器

有时需要将多个装饰器作用于目标函数,使用上和单个装饰器并无区别。下面我们使用两个装饰器作为演示,其实装饰器本质就是传递函数引用,且只能作用于函数。第一个装饰器找不到函数就会向下继续执行,第二个装饰器找到目标函数进行装饰然后返回内部函数,第一个装饰器就以第二个装饰器返回的函数作为目标函数,所以装饰器最后的执行顺序就是装饰器声明的顺序,而装饰的顺序是由近到远(远近是相对于目标函数而言)。

time(func):    ()    ():        start = time.time()        (% start)        func()        end = time.time()        (% (end(end - start)))    wrap(func):    ()    ():        ()        func()        ()    wrap():    ()__name__ == :

保留被装饰函数的__name__属性

目标函数被装饰器装饰后,由于目标函数是作为参数传递到装饰器函数中,而装饰器函数内部是返回嵌套函数的引用,所以查看目标函数的__name__属性时,发现属性名称为装饰器内部嵌套函数名称。我们并不需要对__name__属性进行赋值操作,python内置functools.wraps可以解决这个问题。

functools(func):    ():        func()    wrap(func):    (func)    ():        func()    wrap():    ()():    ()__name__ == :(echo.)


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net