python闭包函数及装饰器简介


  • 目录:

    • 闭包函数简介

    • 闭包函数的实际应用

    • 装饰器简介

    • 装饰器初期-完整版

    • 装饰器语法糖

 

  • 闭包函数简介

  1.定义在函数内部的函数(函数的嵌套)

  2.内部函数运用外部函数局部名称空间中的变量名

  注:函数名还可以当做函数的返回值
  如何接收返回值(统一语法):变量名 = 函数()
  函数名也可以被用来多次赋值

def func(username):
    # username = 'jason'
    def name():
        print(username)
    return name
res = func('jason')
print(res)
res()
  • 闭包函数的实际应用

  • 1.给函数体代码传值方式

    1.1 通过形参传值:在函数定义时定义形参,调用时临时绑定形参与实参完成传值
    def func(username):
        print(username)
    func('jason')       # jason
    1.2 通过闭包函数传值:通过返回值内部函数函数名,通过接收返回值完成传值
    def func(username):
        def name():
            print(username)
        return name
    res = func('jason')
    res()               # jason
    res1 = func('kevin')
    res1()              # kevin
  • 装饰器简介

  • 1.本质:不改变’内部代码’及’调用方式’添加新功能

  • 2.原则:对修改封闭,对扩展开放

  • 3.扩展知识:时间戳

    3.1时间戳:截至目前至1970年1月1日0时0分0秒的秒数
    import time
    print(time.time())      # 1657008257.5792694   
    3.2可以统计代码运行的时间(打印0-1000所需秒数)
    import time
    start_time = time.time()
    for i in range(0, 1000):
        print(i)
    end_time = time.time()
    print('%s'%(end_time-start_time))   # 0.027039527893066406
    3.3睡眠时间 time.sleep(2)括号里的数字代表几秒
    import time
    time.sleep(2)
    print('快睡着了')
  • 装饰器初期-完整版

  • 1.装饰器初期

    1.1 缺陷:如果有多个func函数统计执行时间,则需要多次写代码(统计func函数的执行时间)
    import time
    def func():
        time.sleep(2)
        print('快睡着了')
    start_time = time.time()
    func()
    end_time = time.time()
    print(end_time-start_time)      # 2.002647638320923
    1.2 缺陷:只能统计func函数的执行时间,不能统计其他函数(将多次需要写的代码封装成函数)
    import time
    def func():
        time.sleep(2)
        print('快睡着了')
    def get_time():
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time-start_time)
    get_time()      # 2.0140273571014404
    get_time()      # 2.008859157562256
    1.3 定义的函数存在形参,调用时必须传实参(可以统计多个函数的执行时间)
    import time
    def func():
        time.sleep(2)
        print('快睡着了')
    def username():
        time.sleep(2)
        print('他的名字是kevin')
    def get_time(xxx):
        start_time = time.time()
        xxx()
        end_time = time.time()
        print(end_time-start_time)
    get_time(func)      # 快睡着了   2.005340099334717
    get_time(username)  # 他的名字是kevin  2.0011959075927734
    注:暂无法解决
    import time
    def func1(a):
        time.sleep(2)
        print('我是存在形参的a')
    def get_time(xxx):
        start_time = time.time()
        xxx(*args, **kwargs)  # 暂无法解决
        end_time = time.time()
        print(end_time-start_time)
    get_time(func)
    get_time(username)
    get_time(func1)
    1.4 缺陷:调用函数名发生变化(解决办法:装饰器)
    # 传值方式-参数传值不能改变调用函数方式
    import time
    def get_time(xxx):
        start_time = time.time()
        xxx()
        end_time = time.time()
        print(end_time-start_time)
    get_time(func)
    get_time(username)
    # 传值方式-闭包函数(缺陷:只能计算func函数执行时间)
    def func2():
        xxx = func
        def get_time():
            start_time = time.time()
            xxx()
            end_time = time.time()
            print(end_time-start_time)
        return get_time
    res = func2()
    res()        # 快睡着了   2.0147109031677246
    1.5 所有函数执行时间(可以统计多个函数执行时间、不改变调用函数名,使用闭包函数)
    import time
    def func():
        time.sleep(2)
        print('快睡着了')
    def username():
        time.sleep(2)
        print('他的名字是kevin')
    def func2(xxx):
        # xxx = func
        def get_time():
            start_time = time.time()
            xxx()
            end_time = time.time()
            print(end_time-start_time)
        return get_time
    func = func2(func)
    func()                  # 快睡着了 2.0079562664031982
    username = func2(username)
    username()                 # 他的名字是kevin  2.001535177230835
  • 2.装饰器优化版本(可以统计多个函数执行时间、并且有参无参都可以使用,不改变调用函数名,使用闭包函数)

    import time
    def func(xxx):
        def get_time(*args, **kwargs):   # 形参
            start_time = time.time()
            xxx(*args, **kwargs)      # 实参
            end_time = time.time()
            print(end_time-start_time)
        return get_time
    func2 = func(func2)
  • 3.装饰器完整版本

    import time
    def func(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
  • 4.装饰器最终版本

    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返回值'

     

 

 

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/272960.html

(0)
上一篇 2022年7月9日
下一篇 2022年7月9日

相关推荐

发表回复

登录后才能评论