zoukankan      html  css  js  c++  java
  • 闭包函数

    Python-13

    一、闭包函数

    1. 什么是闭包函数

    • 闭包函数,是定义在一个函数体里面的函数,这个函数有对外部作用域中名字的引用(外层范围:包含对外部作用域而非全局作用域的引用,外部作用域名字不能出最外层的函数)

    2. 闭包函数的基本使用

    def outter(x):  # 也可以使用参数代替,更加灵活,相当于x=1,下面x=1就可以省略了
        # x=1       # 必须要有x=1才叫闭包函数,这个x可以是传进来的参数
        def inner():
            print(x)
        return inner
    
    f=outter(1)
    f()
    
    • 要求:使用函数,获取网站网页的信息
    • 闭包函数相对于普通函数,可以更方便的调用
    • 需要先安装requests模块

    Alt text

    # 方法一:
    import requests
    # 在全局空间里没有url变量值,需要每次调用自己输入
    def get(url):
        respinse=requests.get(url)
        if respinse.status_code == 200:
            print(respinse.text)
    
    baidu=get('https://www.baidu.com') # 这种情况每次调用都要赋值
    
    # 方法二:不用每次调用都输入值
    import requests
    
    def outter(url):
        # 相当于url='https://www.bai.com',不用每次调用都赋值
        def get():
            respinse=requests.get(url)
            if respinse.status_code == 200:
                print(respinse.text)
        return get
    
    baidu=outter('https://www.baidu.com')
    python=outter('https://www.baidu.com')
    baidu()
    python()
    

    二、装饰器(闭包函数的应用)

    1. 什么是装饰器

    • 装饰器:可以为其他函数添加额外的功能,装饰器就是函数(暂时理解为函数)
    • 装饰器本身可以是任意可调用的对象,即,被装饰的对象也可以是任意可调用的对象

    2. 装饰器必须遵循的两大原则

    • 不修改被装饰对象的源代码
    • 不修改被装饰对象的调用方式
    • 背景原因:软件的维护应该遵循开放封闭原则,即,软件一旦上线运行后,对修改源代码是封闭的,但是对扩展功能是开放的

    3. 无参装饰器

    import time
    def index():
        print('welcome to index')
        time.sleep(3)
    要求:添加显示代码运行多长时间的功能,使用装饰器来完成
    
    方法一:
    def wrapper():
        start=time.time()
        index()
        stop=time.time()
        print('run time is %s' %(stop-start))
    问题:虽然功能实现了,但是改变了调用方式
    
    方法二:
    def timmer():
        func=index
        def warpper():
            start=time.time()
            func()
            stop=time.time()
            print('run time is %s' % (stop - start))
        return warpper
    
    f=timmer() # 相当于f=warpper
    问题:这种形式func=index被固定住了,不能更换其他参数,因此需要将func当做传参使用
    
    方法三:
    def timmer(func):
        # 就相当于func=index
        def warrpper():
            start=time.time()
            func()
            stop=time.time()
            print('run time is %s' %(stop-start))
        return warrpper # 打破层级限制就需要函数对象
    f=timmer(index)   # 参数为被装饰函数的内存地址
    f()
    问题:目的是让用户使用方式和以前一样,即,以index()的形式调用函数,需要将最后改为如下形式
    index=timmer(index)   # index不同命名空间的名字不冲突
    index()
    
    • 说明:time.time() 表示当前时间

    4. 装饰器修正

    ① 返回值修正

    如果被装饰的函数,有返回值需求

    Alt text

    import time
    def index():
        print('welcome to index')
        time.sleep(3)
        return 123
    
    def timmer(func):
        def wrapper():
            start=time.time()
            res=func()
            stop=time.time()
            print('run time is %s' % (stop - start))
            return res
        return wrapper
    
    index=timmer(index)
    res=index()
    print(res)
    

    ② 参数修正

    • 被修饰函数,有传入参数的需求,要求可以接收任意形式的参数
    import time
    def index():
        print('welcome to index')
        time.sleep(3)
        return 123
    
    def home(name):
        print('My name is %s' %name)
    
    def timmer(func):
        def wrapper(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' % (stop - start))
            return res
        return wrapper
    
    index=timmer(index)
    home=timmer(home)
    home('xdw')
    

    Alt text

    ③ 装饰器语法糖

    语法格式:

    装饰器放上面
    @(Python)装饰器名字(说明:单独一行)
    被装饰函数
    

    @装饰器名字的作用:

    • 把正下方的函数名作为参数,传给自己,相当于装饰器名字(正下方函数名)(说明:单独一行)
    • 然后,将返回值,赋值给原函数名,代替了:index=timmer(index)
    import time
    # 装饰器函数
    def timmer(func):
        def wrapper(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' % (stop - start))
            return res
        return wrapper
        
    @timmer  # @装饰器名称
    # 被装饰器函数
    def index():
        print('welcome to index')
        time.sleep(3)
        return 123
     
    @timmer   # 多个函数需要装饰,就需要写多个,@装饰器
    def home(name):
        print('My name is %s' %name)
    
    # 调用 
    index()
    home('egon')
    

    4. 装饰器的基本形式

    def deco(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs) # func为被装饰对象
            return res
        return wrapper
    
  • 相关阅读:
    C# listbox鼠标选择改变改行颜色的另一种方便方法
    非专业码农 JAVA学习笔记 4 java继承和多态
    转:Java学习笔记之方法重载,动态方法调度和抽象类
    非专业码农 JAVA学习笔记 3 抽象、封装和类(2)
    使用bootstrap简单制作Tab切换页
    转载:CSS从大图中抠取小图完整教程(background-position应用)
    xhEditor 整理用法
    SCADA开源项目lite版本
    ImageSharp源码详解之JPEG压缩原理(3)DCT变换
    ImageSharp源码详解之JPEG压缩原理(4)熵编码
  • 原文地址:https://www.cnblogs.com/itone/p/9524555.html
Copyright © 2011-2022 走看看