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

20210111 装饰器之案例剖析

来源:本站原创 浏览:89次 时间:2022-03-17

高阶函数
a: 把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b: 返回值中包含函数名(不修改函数的调用方式)

# 现在写一个装饰器# 两个函数都有自己的逻辑,能够实现自己的功能# 写一个装饰器,统计函数运行时间1-1import timedef test1():    time.sleep(3)    print('in the test1')def test2():    time.sleep(3)    print('in the test2')# 统计test1 �ķ�,�߻�和 test2 的运行时间,但是前提是不能修改调用方式
1-1-1# 如何不修改源代码,给 test1 新增一个功能?import timedef test1():    time.sleep(3)    print('in the test1')def test2():    time.sleep(3)    print('in the test2')# 写一个高阶函数def deco(func):    start_time = time.time()    func()    stop_time = time.time()    print("the func run time  is %s" %(stop_time-start_time))# 那么怎么用?# 为什么 test1 不加括号,因为test1(),传入的是返回值结果deco(test1)deco(test2)--->in the test1the func run time  is 3.0043373107910156in the test2the func run time  is 3.0002830028533936
1-1-2# 1-1-1 修改了函数的调用方式# 如何不修改函数的调用方式?# 第二类高阶函数,不改变函数的调用方式,在使用的时候就是 test1 = deco(test1) 这种方式# 但是前提是 需要把函数修改成 用 return 返回函数名的 第二种形式的高阶函数# 这样,test1 就可以获取 deco 的返回值,deco 的返回值就是 test1 的 内存地址# test1() 可以正常调用,test2()也可以def deco(func):    start_time = time.time()    return func    stop_time = time.time()    print("the func run time  is %s" %(stop_time-start_time))import timedef test1():    time.sleep(3)    print('in the test1')def test2():    time.sleep(3)    print('in the test2')test1 = deco(test1)test1()test2 = deco(test2)test2()--->in the test1in the test2# 没有修改函数的调用方式,也没有新增功能,什么都没有做# 为什么是这样呢?# 因为 deco 中的 return,直接调用了 test1;# 之后的内容不会执行,这就是 return 的一个特性
1-1-3# 因为 1-1-2 中一直在用高阶函数,漏掉了嵌套# 可以引入嵌套函数def deco(func):    start_time = time.time()    return func    stop_time = time.time()    print("the func run time  is %s" %(stop_time-start_time))def timer():    def deco():        pass# 这是嵌套函数,如何把这个函数,融入到上面的 deco中呢?
1-1-4import timedef timer(func):    # timer(test1)  把 test1 的内存地址 传给 func = test1    def deco():        start_time = time.time()        func()        stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     # 返回 deco 函数的内存地址# 这么做以后,用到了高阶函数,用到了函数嵌套def test1():    time.sleep(3)    print('in the test1')def test2():    time.sleep(3)    print('in the test2')timer(test1)print(timer(test1))     # 返回 deco 的内存地址---><function timer.<locals>.deco at 0x000002C818B1D558>
1-2# 想要调用 timer(test1) 应该怎么做?# 给它赋值,然后 test1 执行就可以import timedef timer(func):    # timer(test1)  把 test1 的内存地址 传给 func = test1    def deco():        start_time = time.time()        func()      # run test1()        stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     # 返回 deco 函数的内存地址# 这么做以后,用到了高阶函数,用到了函数嵌套def test1():    time.sleep(3)    print('in the test1')def test2():    time.sleep(3)    print('in the test2')test1=timer(test1)test1()     # 这时候,test1 执行,实际上是在执行 deco 函数,因为 timer 返回的是 deco;deco做的事情是计算时间; func 的值是 test1 的值--->in the test1the func run time  is 3.000483751296997# 成功加了一个新功能,没有改变源代码和调用方式;# 用到函数的嵌套,引用高阶函数的定义,最终实现这样的效果
1-3# 但是 1-2 那样# test1=timer(test1)# test1()# 这种方式,有些麻烦;每次都需要运行装饰器,运行一个和原来函数名一样的东西# 如何直接 test1() 运行呢?# 解释器提供了一种语法,直接加 @timer;@ 后加上装饰器的名字;写在想要新增功能的函数的头部# @timer 就等同于 test1 = timer(test1) 这部操作import timedef timer(func):        def deco():        start_time = time.time()        func()              stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     @timerdef test1():    time.sleep(3)    print('in the test1')@timerdef test2():    time.sleep(3)    print('in the test2')test1() test2()--->in the test1the func run time  is 3.000530958175659in the test2the func run time  is 3.000612497329712# 这两个函数正常运行了,同时加上了新功能
1-1# 如果 test2 里面有一个参数import timedef timer(func):        def deco():        start_time = time.time()        func()              stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     @timerdef test1():    time.sleep(3)    print('in the test1')@timerdef test2(name):    print("test2:",name)test1() test2()--->TypeError: test2() missing 1 required positional argument: 'name'# 结果是出错的,test2 缺少位置参数 name# @timer 相当于 test2 = timer(test2) # test2 传到里面都做了什么? test2 → func → 执行 deco 所以,内嵌的deco函数,执行了吗?# return deco,直接返回了 deco 的内存地址# test2 其实是等于 deco,于是 test2()相当于 deco(),执行到 func()时,相当于执行到了 test2()# 但是 test2 是要求传参数的,test2()没有传参;所以会报错# 那么,这种情况应该如何处理?如何把参数传进来?
1-2# test2(name),其实就是相当于 deco(name)import timedef timer(func):        def deco(arg1):        start_time = time.time()        func(arg1)              stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     @timerdef test2(name):    print("test2:",name)test2("alex")--->test2: alexthe func run time  is 0.0
1-2-1# 如果传入两个参数呢?# 要装饰的函数可能是各种各样的功能# 所以需要 *args  **kwargsimport timedef timer(func):        def deco(*args,**kwargs):        start_time = time.time()        func(*args,**kwargs)              stop_time = time.time()        print("the func run time  is %s" %(stop_time-start_time))        return deco     @timerdef test1():    time.sleep(3)    print('in the test1')@timerdef test2(name,age):    print("test2:",name,age)test1()test2("alex",11)--->in the test1the func run time  is 3.0008721351623535test2: alex 11the func run time  is 0.0009975433349609375

  推荐站点

  • 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