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

    闭包函数

      什么是闭包函数:内部函数对外部函数作用域而非全局全局作用域中的变量引用,那么该函数就叫闭包函数

      (闭包函数必须定义在函数内部,可以使用外层函数的名字)

        闭包函数是函数嵌套,函数对象,名称空间与作用域的结合体

    #直接传参
    def func(number):
        print(number)
    
    
    func(10)
    >>10
    
    
    #通过闭包传参
    def outer(number):
        def inner(): #inner闭包函数
            print(number)
        return inner #将inner当做参数返回
    
    
    inner = outer(10)
    inner()
    >>10

    闭包函数的应用:  为了装饰器做准备

    函数体传值的方式:1.直接将值以参数的形式传入;2.将值包给函数

    例子:  

      爬取某个网站,打印获取数据的长度

    # 方式一 直接传参
    import requests
    
    
    def spider_func(url):
        # 往url地址发送请求,获取响应数据
        response = requests.get(url) # 必须接收url
        # 状态码 200
        if response.status_code == 200:
            #获取当前url地址中文本长度
            print(len(response.text))
            #获取当前url地址所有文本
            print(response.text)
            print(response.status_code)
    
    
    url = 'https://www.baidu.com'
    spider_func(url)
    #方式二 通过闭包函数接受url地址,执行爬取函数
    import requests
    
    
    def spider_func(url):
        def spider_inner():
            response = requests.get(url)
            if response.status_code == 200:
                print(len(response.text))
        return spider_inner
    
    
    spider_page = spider_func('https://www.baidu.com/')
    spider_page()

    装饰器:装饰的工具

      装饰器必须要遵循“开放封闭”原则

        开放:对函数功能的添加是开放的

        封闭:对函数功能的修改是封闭的

      装饰器的作用:在不修改被装饰对象源代码与调用方式的前提下,添加新的功能

      装饰器必须遵循:*不修改被装饰对象源代码  *不修改被装饰对象的调用方式

      怎么使用装饰器:

        装饰器的应用:*统计时间 *登录认证......

      为什么使用装饰器:可以解决代码冗余,提高代码的可扩展性

      编写编写装饰器:通过闭包函数编写

    例子:

      需求:统计电影的下载时间

    import time
    
    
    def movie_download():
        print('start download')
        time.sleep(3)
        print('download completed')
        return 'nmb'
    
    
    # start_time = time.time()
    # movie_download()
    # end_time = time.time()
    # print(f'time cost:{end_time-start_time}')
    #缺点:当有多个装饰对象时,需要编写多次统计时间代码,导致代码冗余
    
    
    
    # 添加计时功能
    def time_record(func):
        start_time = time.time()
        # movie_download()   若这么写 该功能只能给movie_download()使用
        func()
        end_time = time.time()
        print(f'time cost:{end_time - start_time}')
        return None
    
    res = time_record(movie_download)
    print(res)

    完善装饰器

    import time
    
    
    def time_record(func):
        def inner(*args,**kwargs): # *args, **kwargs接收所有参数
            start_time = time.time()
            # 将被装饰对象需要接收的任意参数 原封不动传给func --》 被装饰对象
            res = func(*args,**kwargs) # func(url) ---> download_movie(url)
            end_time = time.time()
            print(f'time cost:{end_time-start_time}')
            return res
        return inner
    
    def movie_download():
        print('start download')
        time.sleep(3)
        print('download completed')
        return 'nmb'
    
    
    movie_download = time_record(movie_download)
    movie_download()

    装饰器语法糖:

      在使用语法糖时,装饰器必须在被装饰对象前定义

      

    import time
    
    
    def wrapper(func):
        def inner(*args,**kwargs):
            start_time = time.time()
            res = func(*args,**kwargs)
            end_time = time.time()
            print(f'{end_time-start_time}')
            return res
        return inner
    
    # 使用装饰器语法糖
    @wrapper
    def func():
        print('start')
        time.sleep(3)
        print('end')
    func()
    
    # 不使用语法糖
    func = wrapper(func)
    func()

    装饰器模板

    def wrapper(func):
        def inner(*args,**kwargs):
            #功能输入区
            
            res = func(*args,**kwargs) # 调用被装饰对象,得到返回值
            
            #功能输入区
            return res
        return inner
    
    def func():
        pass
    
    func = wrapper(func)
    func()
  • 相关阅读:
    clearfix
    css浮动
    css常识
    给数组排序方法2
    定时器
    数组
    redhat 7.6 iptables 配置
    redhat 7.6 流量监控命令、软件(3)nethogs 监控进程实时流量
    redhat 7.6 流量监控命令、软件(2) iftop 监控网络IP实时流量
    redhat 7.6 流量监控命令、软件(1) ethstatus
  • 原文地址:https://www.cnblogs.com/littleb/p/11842211.html
Copyright © 2011-2022 走看看