zoukankan      html  css  js  c++  java
  • 闭包函数和装饰器

    闭包函数和装饰器

    一-什么是闭包函数?

    	闭:封闭
    

    ​ 包:包裹

    ​ 比如手机的举例

    ​ 1.闭包函数必须在函数内部定义

    ​ 2.闭包函数可以引用外层函数的名字

    ​ -闭包函数是:函数的嵌套、函数的对象、名称空间和作用域 结合体。

    ​ ****闭合函数是为了装饰器做准备

    def func(y):
        x = 100
        #inner 是一个闭包函数
        def inner():
            print(x)
            print(y)
        return inner
    inner = func(1)
    inner()
    >>>>>>
    100
    1
    

    二、装饰器

    ​ -什么是装饰器?

    ​ 装饰:装饰 ,修饰。

    ​ 器:工具

    ​ ***开放封闭 装饰器必须遵循“开放封闭“的原则

    ​ -开放:

    ​ 对函数的功能添加是开放的;

    ​ -封闭:

    ​ 对函数的功能修改是封闭的。

    ​ -装饰器的作用?

    ​ -在不修改被装饰对象的源代码和调用方式前提下,添加新的功能。

    ​ ##装饰器的定义必须遵顼:

    ​ -不修改被装饰对象的源代码

    ​ -不修改被装饰对象的调用方式

    ​ -为什么要使用装饰器?

    ​ 可以解决代码冗余问题,提高代码的可扩展性

    ​ -怎么使用装饰器?

    ​ -装饰器的应用:

    ​ -登录时间

    ​ -登录认证

    ​ -编写装饰器

    ​ 通过闭包函数来实现装饰器

    #爬虫的获取技术
    import requests # 爬虫请求工具,外国大佬给我们提供的爬虫的第三方请求库
    #方式一直接传参
    def spider_func(url):  #往url发送请求,获取相响应数据
        response =  requests.get(url)  #必须接受url
        if response.status_code ==200:
            #状态码:200
            print(len(response.text)) #获取当前的url中所有文本
            print(response.text)
    url = 'https://fanyi.baidu.com/#en/zh/spider'
    spider_func(url)
    >>>>>>>>>
    219724    ###len
    <!DOCTYPE html> ####文本
    <html>
    <head>
    
    用闭包函数的方法
    def wrapper(url):
        def spider_func():
            response = requests.get(url)
            if response.status_code == 200:
                print(len(response.text))
                print(response.text)
        return spider_func  #return 的位置一定要特别注意
    url ='https://fanyi.baidu.com/#en/zh/spider'
    spider_baidu = wrapper(url)
    spider_baidu()
    >>>>>>>>
    # 功能: 统计下载电影的函数的运行时间
    import time
    def downlode_moive():
        print('开始下载电影......')  #模拟下载电影
        time.sleep(5)#等待3秒钟
        print('电影下载成功......')#电影下载成功
        return '千与千寻.mp4'
    
    start_time = time.time()  #获取当前时间戳
    downlode_moive()
    end_time = time.time()#获取当前时间戳
    print(f'下载消耗的时间{end_time - start_time}')
    
    
    # 功能: 统计下载电影的函数的运行时间
    import time
    def download_movie():
        print('开始下载电影......')  #模拟下载电影
        time.sleep(2)#等待3秒钟
        print('电影下载成功......')#电影下载成功
        return '千与千寻.mp4'
    #
    # start_time = time.time()  #获取当前时间戳
    # download_movie()
    # # end_time = time.time()#获取当前时间戳
    # print(f'下载消耗的时间{end_time - start_time}')
    
    def download_record(func):
        def inner_movie():
            start_time = time.time()
            res = func()
            end_time = time.time()
            print(f'消耗时间:{end_time - start_time}')
            return res
        return inner_movie
    
    download_movie = download_record(download_movie)####调用函数有个先后的顺序,download_moive---》inner时候 调用了inner函数,执行download——moive ,最下面的还没有轮到执行
    download_movie()
    >>>>>>>
    开始下载电影......
    电影下载成功......
    消耗时间:2.00022292137146
        
     #####被接收对象接收2个参数   
    import time
    def download_movie(a,c):
        print(f'{a,c}电影开始下载......')
        time.sleep(2)
        print('电影下载完成......')
        return '太阳.mp4'
    
    def download_record(func):
        def inner_movie(a,c):
            # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
            start_time = time.time()
            res = func(a,c)
            end_time = time.time()
            print(f'下载时间:{end_time - start_time}')
            print(res)
    
        return inner_movie
    download_movie = download_record(download_movie)
    download_movie('avd',c = 'dfe')
    >>>>>>>>
    ('avd', 'dfe')电影开始下载......
    电影下载完成......
    下载时间:2.000197410583496
    太阳.mp4
    
    ####被装饰的对象接收多个参数
    import time
    def download_movie(*arg,**kwargs):
        print(f'{*arg,kwargs}电影开始下载......')
        time.sleep(2)
        print('电影下载完成......')
        return '太阳.mp4'
    
    def download_record(func):
        def inner_movie(*arg, **kwargs ):
            # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
            start_time = time.time()
            res = func(*arg,**kwargs)
            end_time = time.time()
            print(f'下载时间:{end_time - start_time}')
            print(res)
    
        return inner_movie
    download_movie = download_record(download_movie)
    download_movie('avd','dfe',url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html')
    >>>>>>>>
    C:Users86187AppDataLocalProgramsPythonPython36python.exe E:/PycharmProjects/study/11.8.py
    ('avd', 'dfe', {'url': 'https://www.cnblogs.com/wangeraaa/p/10236180.html'})电影开始下载......
    电影下载完成......
    下载时间:2.001342296600342
    太阳.mp4
    
    

    装饰器的完整最终模板

    def func1():#####被装饰的对象
        pass
    
    def wrapper(func):
        def inner(*arg, **kwargs):
            #让用户输入内容
            username = input('请输入你的名字:')
            if username == 'tank':
                print('right')
                res = func(*arg, **kwargs)
                return res
            else:
                print('wrong')
        return inner
    
    func1 = wrapper(func1)
    func1()
    

    语法糖

    '''
    装饰器的语法糖,是属于装饰器的。 语法糖是python内置的,可以引用所有的装饰器
    @: 装饰器的语法糖
    
    # 注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。
    '''
    import time
    
    
    # 统计函数执行时间装饰器
    def wrapper(func):  # 被装饰对象
        def inner(*args, **kwargs):  # 被装饰对象的参数
            # 调用前增加新功能
            start_time = time.time()
            # 调用被装饰对象,并接收返回值
            res = func(*args, **kwargs)
    
            # 调用后添加新功能
            end_time = time.time()
            print(end_time - start_time)
    
            return res
        return inner
    
    
    # func函数需要执行3秒
    
    # 无参装饰器
    # 使用装饰器
    @wrapper  # wrapper(func)  ---> func
    def func():
    
        time.sleep(3)
        
    func()
    
    
    # # 不用装饰器
    # def func2():
    #     time.sleep(3)
    #
    # func()
    举例如下
    import time
    def download_record(func):
        def inner_movie(a,c):
            # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
            start_time = time.time()
            res = func(a,c)
            end_time = time.time()
            print(f'下载时间:{end_time - start_time}')
            print(res)
    
        return inner_movie
    # download_movie = download_record(download_movie)
    # download_movie('avd',c = 'dfe')
    @download_record
    def download_movie(a,c):
        print(f'{a,c}电影开始下载......')
        time.sleep(2)
        print('电影下载完成......')
        return '太阳.mp4'
    
    download_movie('ss','fff')
    >>>>>>>>>>
    ('ss', 'fff')电影开始下载......
    电影下载完成......
    下载时间:2.0004498958587646
    太阳.mp4
    
    
  • 相关阅读:
    第5.3课.多输入之多线程和fork
    第5.2课多输入之select
    第5.1课,多输入之轮询
    第4课.编写通用的Makefile
    第3课.电子书框架
    2.3freetype矢量字体
    建立u-boot,内核的SI工程
    2.1/2.2字符的编码方式及显示
    1.0数码相框框架分析
    [数据结构]一些有意思题目(一)
  • 原文地址:https://www.cnblogs.com/bs2019/p/11844312.html
Copyright © 2011-2022 走看看