装饰器
闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数使用了外层函数名称中的名字
def outer():  #外部函数
    x = 999
    def inner():   #内部函数:使用的是外层函数的返回值
        print('from outer>>>inner',x)
    return inner(外层函数的返回值)
x = 666
res = outer()   #相当于inner(因为打印res,就是返回值inner)
res()   #执行inner
闭包函数实际应用
函数体传参方式:
1.形参
def index(username):     #直接通过形参传
    print(username)  
index('jason')即可调用 
2.闭包
def outer(username):#为了让里面的名字都可以变,使用形参(由于已经使用了一个外包了,就不使用了) def index(): print(username) return(index) res = outer('jason') #这里的res就是index
res() #调用index函数
装饰器简介
装饰器不是新知识的,就是前几天学习的名称空间/函数名/闭包函数。。。的产物
本质:不改变越来的调用方式和内部代码的情况下给装饰器添加新的功能
原则:对扩展开放,对修改封闭
小知识点:
①import time
print(time.time())  #1647568920.168808
'''上述的数字是时间戳:1970年1月1日0时0分0秒距离刚刚代码运行间隔的秒数'''
②time.sleep(3)  #让程序原地等待三秒
统一测量函数执行时间
import time
def index():
    time.sleep(3)
    print('from index')
'''现在给index增加一个统计执行时间的功能'''
 start_time = time.time() # 函数执行之前获取一个时间戳
index()
end_time = time.time() # 函数执行之后获取一个时间戳
print(end_time - start_time) # 两个时间戳的差值就是函数的执行
装饰器进化过程
简易版本 
在很多地方都需要执行统计index函数执行时间的代码
        在不同的地方需要执行相同的代码      >>>:       函数
import time def index(): time.sleep(1) print('from index') def outer(func): # 真正的index被outer局部名称空间func存储了 def get_time(): start_time = time.time() # 函数执行之前获取一个时间戳 func() # 调用了真正的index函数 end_time = time.time() # 函数执行之后获取一个时间戳 print(end_time - start_time) # 两个时间戳的差值就是函数的执行时间 return get_time
index = outer(index)#右边调用outer函数,返回get_time,调用出get_time函数,测量函数index时间(这个时候的func就是index)
index
()#调用get_time函数
这里的左边的index是普通变量名,也可以是a(狸猫换太子,为了后面调用时候一样,其实这里左边的index是get_time)
进阶版本装饰器
# 解决的是参数问题
def outer(func_name):
    def get_time(*args, **kwargs):
        start_time = time.time()
        func_name(*args, **kwargs)
        end_time = time.time()
        print(end_time - start_time)
    return get_time
完整版本装饰器
# 解决的是返回值问题
def outer(func_name):
    def get_time(*args, **kwargs):
        start_time = time.time()
        res = func_name(*args, **kwargs)  # 执行真正的index函数
        end_time = time.time()
        print(end_time - start_time)
        return res  #此时的res就是index函数,res的返回值就是index的返回值
    return get_time
装饰器模板!
'''编写装饰器其实有一套固定的代码 不需要做任何理解'''
def outer(func_name):  # func_name用于接收被装饰的对象(函数)
    def inner(*args, **kwargs):
        print('执行被装饰函数之前 可以做的额外操作')
        res = func_name(*args, **kwargs)  # 执行真正的被装饰函数
        print('执行被装饰函数之后 可以做的额外操作')
        return res  # 返回真正函数的返回值
    return inner
 #仅仅是让代码编写的更加好看、简洁!!!
def outer(func_name):
    def inner(*args, **kwargs):
        print('执行函数之前的操作')
        res = func_name(*args, **kwargs)
        # 额外操作
        return res
    return inner
index = outer(index)  #左边的index是outer函数的返回值inner(但是这一行太low了!)
index()  #相当于调用inner函数
print(index)  #打印inner函数的返回值res,而res的返回值就是index的返回值
以后这么写
@outer  # 等价于 index = outer(index)    #相当于装饰器直接装上了,方便!!
def index(*args, **kwargs):
    print('from index')
以后调用,直接用
index()
看返回值也直接用
print(index)
防止有些人查看位置,看到位置改变,比如使用print打印函数位置,前后变化
用help去看指定函数的注释信息,eg     help(home)  所有有瑕疵
# # 做到比真的还要真  但是本质其实没有变
from functools import wraps
def outer(func_name):
    @wraps(func_name)
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的操作')
        res = func_name(*args, **kwargs)
        return res
    return inner
@outer
def index():
    print('from index')
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号