今日内容回顾7.5

闭包函数简介

闭包函数

定义在函数内部的函数,内部函数使用了外部函数名称空间中的名字称之为闭包函数。

基本使用

def func(name ): 
    def index():
        print(name)
    return index
s =func('jason')
s()

装饰器简介

装饰器的本质

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

装饰器的原则

对修改的封闭 对扩展的开发

知识储备

import time

# print(time.time())  # 1656987566.7260265
'''时间戳(秒数):当前距离1970年1月1日0时0分0秒所经历的秒数'''
# 实际应用>>>:统计代码的运行时间
# start_time = time.time()  #  100
# for i in range(1000):
#     print(i)
# end_time = time.time()
# print('for循环的执行时间是:%s'%(end_time - start_time))
time.sleep(3)
'''让程序原地等待三秒'''
print('等待3秒')

装饰器的推导流程

将下列代码在不改变被装饰对象原有的调用方式和内部代码的情况下给装饰对象添加新的统计执行时间功能。

def index():
    time.sleep(3)
    print('from index')
    '''统计index函数的执行时间'''
start_time = time.time()  # 在调用index函数之前获取一下时间戳
index()  # 调用index函数
end_time = time.time()
print(end_time - start_time)
 """
缺陷
    如果有多个index需要统计时间 则需要重复编写代码
    解决措施:
        封装成函数
"""

装饰器的初始阶段

"""
# def get_time():
#     start_time = time.time()  # 在调用index函数之前获取一下时间戳
#     index()  # 调用index函数
#     end_time = time.time()
#     print('函数的执行时间是:',end_time - start_time)
"""
缺陷
    如果有多个不同的函数需要统计时间 那么上述的解决措施不够完善
    解决措施: 
        给函数体添加形参(动态传参)  
"""

装饰器的优化阶段

def home():
    time.sleep(5)
    print('from home')

def get_time(xxx):
    start_time = time.time()  # 在调用index函数之前获取一下时间戳
    xxx(*args,**kwargs)  # 调用index函数
    end_time = time.time()
    print('函数的执行时间是:',end_time - start_time)
# get_time(index)
# get_time(home)
"""
缺陷
    不同形参个数的函数无法兼容统计
    解决措施:
        *args  **kwargs
    但是在我们目前的代码中无法实现(暂且忽略)
"""

装饰器的完整阶段

import time

"""针对有参无参函数如何兼容问题"""
def outer(xxx):  # 定义一个函数,设置一个形参xxx用来绑定被装饰的对象。
    def get_time(*args, **kwargs):  # 定义一个内层函数用来间接调用装饰的对象,形参中用*和**的作用来兼容有参或者无参的装饰对象。
        start_time = time.time()  # 在调用被装饰对象之前获取一下时间戳
        res = xxx(*args, **kwargs)  # 调用outer形参中接受的被装饰对象,并将被装饰的对象返回值赋值给res,
        end_time = time.time()   # 调用被装饰对象之后获取一下时间戳
        print('函数的执行时间是:', end_time - start_time)  # 算出前后的时间差。
        return res # 将被装饰对象的返回值返回给get_time。
    return get_time # 将函数get_time功能当作返回值返回给outer函数

def home():
    time.sleep(2)
    print('from home')
    return '执行home函数之后的返回值'

def index(name):
    time.sleep(1)
    print('from index')
    return '执行index函数之后的返回值'

home = outer(home)
xxx = home()
print(xxx)


index = outer(index)
res = index('jason')
print(res)

装饰器的终极阶段

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
# def home():
#     time.sleep(1)
#     print('from home')
#     return 'home返回值'


# home = outer(home)
# res = home()
# print(res)
"""
执行home函数之前需要添加校验用户身份的功能
"""

# 装饰器语法糖
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)

装饰器模板。

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

posted @ 2022-07-05 21:06  瓮小辉  阅读(23)  评论(0)    收藏  举报