ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python基础17-闭包函数-无参装饰器

2022-07-06 22:03:10  阅读:148  来源: 互联网

标签:闭包 无参 函数 17 index time print home def


今日学习

闭包函数简介

闭包函数的实际应用

装饰器简介

装饰器推导流程(重要)

装饰器功能完善

装饰器统一使用模板(通用)

装饰器语法糖

装饰器修复计数(待补充)

闭包函数概念

1.定义在函数内部的函数

2.内部函数使用了外部函数名称空间的名字

ps:只有符合上述两个特征的函数才能称为闭包函数
---------------------------
def warapper(username):               #定义warapper函数 username是形参
    #username = 'jason'      
    def index():
        print(username)
    return index

res()

闭包函数的实际应用

import requests
 
#方式一:
def get(url):
    return requests.get(url).text
 
#方式二:
def page(url):                1. #url为形参,page(https:xx实参)相
    def get():                2. #还未调用不看。
        return requests.get(url).text       3. #get获取(url)形参位
    return get                   4.#返回get

# 方式一下载同一页面
get('https://www.python.org')
get('https://www.python.org')
get('https://www.python.org')
……
 
# 方式二下载同一页面
python=page('https://www.python.org')      #将page('https://www.python.org')传给python
python()
python()
python()
……

装饰器

可以理解为:闭包+函数对象+嵌套

在不改变被装饰对象原来的调用方式内部代码的情况下,给被装饰对象添加新的功能

  • 装饰器推导

    -------------------------问题运行代码块并打印出代码块运行时间--------------------------
    # 改变了代码冗余问题(函数传参)
    import time
    #
    # 需求,打印
    # #函数传参 案例一
    # def index(x, y):
    #
    #     start = time.time()
    #     time.sleep(3)
    #     print('index %s %s' % (x, y))
    #     stop = time.time()
    #     print(stop - start)
    # index(111,222)
    #但是需求一次,我们就要做一次print打印,代码冗余繁琐。将print和time优化成函数体
    ------------------------------------------------------------
    
    # #函数传参 方案二
     def index(x,y):
          time.sleep(3)
          print('index %s %s' % (x, y))
     def wrapper():
         start = time.time()
         index(1111, 2222,111) #太死板,如果有改变的话,代码会冗余,位置实参不填写正确也会报错。
         stop = time.time()
         print(stop - start)
     wrapper()
    #此时我们将index(1111, 2222,111)打印需求修改,还有改代码。
    ----------------------------------------------------------------------------
     方案3:方案三优化一  将index(x,y)传参,设置wrapper
    
    # 函数传参
     def index(x,y):
          time.sleep(3)
          print('index %s %s %s' % (x, y))
     def wrapper(g,z):
         start = time.time()
         index(g,z)
         stop = time.time()
         print(stop - start)
    # 打印
     wrapper(111,2223)
        
    -----------------------------------------------------------------------------------
    # 方案3优化二 优化wrapper函数,将index方案写活了
    
     def index(x,y,z):
          time.sleep(2)
          print('index %s %s %s' % (x, y, z))
    
     def wrapper(*args,**kwargs):
         start = time.time()
         index(*args,**kwargs)      #warapper  灵活了,但是index比较死板,如果是再新增home功能,
         stop = time.time()          # 还要再多写一遍函数体,所以尽可能的把index给做成变量。
         print(stop - start)
     wrapper(111,2223,33333)
    -----------------------------------------------------------------------------------
    
    # 方案3优化三#除了将设置warapper函数体后,将函数体内的index优化为传参。
    def index(x, y, z):
        time.sleep(2)
        print('index %s %s %s' % (x, y, z))
    	print(index)
    
    def outer(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            func(*args, **kwargs)  # func实参成为了index,(*args,**kwargs)变为(x,y,z)
            stop = time.time()
            print(stop - start)
        return wrapper
    
    index = outer(index)      #新定义index变量
    index(11,22,33)         
    # func(11,22,33)
    # 1.将index函数 赋值传给上面函数体中的func形参中,此时outer函数形参传给内层函数体(wrapper)下的func
    
  • 推导总结

    1.统计某个函数的运行时间
    2.将统计函数运行时间的代码封装成了函数
    3.直接封装成函数会改变调用方式
    4.利用闭包函数传参尝试
    5.利用重名替换原来函数名的功能
    6.函数的参数
    7.函数的返回值装饰器各种版本
    
  • 装饰器各个版本

    import time
    def home():
        time.sleep(2)
        print('from home')
        return '执行home函数之后的返回值' 
    
    """针对有参无参函数如何兼容"""
    def outer(xxx):
        def get_time(*args, **kwargs):
            start_time = time.time()  
            res = xxx(*args, **kwargs)  
            end_time = time.time()
            print('函数的执行时间是:', end_time - start_time)
            return res
        return get_time
    
    # @outer#装饰语法糖  #home = outer(home)
    home = outer(home)        #outer(home)将home传参给outer(xxx)
    xxx = home()
    print(xxx)
    
    ------------------执行结果--------------------------------
    from home
    函数的执行时间是: 2.008957624435425
    执行home函数之后的返回值
    
    ----------------装饰器叙述总结----------------------
    1.首先定义了home代码功能块,然后outer为无参装饰器(可以理解为嵌套函数outer(xxx)函数体);
    
    2.因为xxx为形参位,outer(home) 就是home作为实参传入xxx形参中。
    3. 闭包函数内层中res = xxx(*args, **kwargs)  相当于 res = home()
    4.res变量 返回结果给get_time
    5.get_time函数返回结果
    6.定义一个新的home变量 home = outer(home)
    7.home()调用
    

拓展小知识-return

  • def add(x, y):
        z = x + y
        return  z
    # print(add(x, y))       #不加return  返回none
    print(add(1,2))  
    -----结果------
    3
    --------------------
    return返回值只能通过print打印才会显示出来,但在交互式模式下不需要print打印-------
    return的作用之一是返回计算的值
    
  • 固定模板

    ---------------- 使用方法  模板 +@outer+代码块-------------------
    
    from functools import wraps               #装饰器的修复技术
    def outer(func_name):
        @wraps(func_name)  # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真
        def inner(*args, **kwargs):
            print('执行被装饰对象之前可以做的额外操作')
            res = func_name(*args, **kwargs)
            print('执行被装饰对象之后可以做的额外操作')
            return res
        return inner
    
    
    
  • 装饰器语法糖

    # 装饰器语法糖
    import time
    
    @outer  #  home = outer(真正的函数名home)
    def home():
        '''我是home函数 我要热死了!!!'''
        time.sleep(1)
        print('from home')
        return 'home返回值'
    
    # help(home)
    # print(home)
    home()
    
    # def index():
    #     '我是index函数 我的功能很强大'
    #     pass
    #
    # help(index)
    

标签:闭包,无参,函数,17,index,time,print,home,def
来源: https://www.cnblogs.com/zongliang-ya/p/16452712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有