1、代码
# 2021年12月07日,第四周1~7
# !/usr/bin/env python
# -*- coding: utf-8 -*-
import time
def time_low_low(func): # 计算函数运行时间
start_time = time.time()
func()
stop_time = time.time()
print("不使用装饰器:the func run time is %s" % (stop_time - start_time))
return func
def day10_case():
print("不使用装饰器")
# 装饰器:装饰器本质是函数(装饰函数),为函数添加功能,不修改原函数代码
# 装饰器 =》 高阶函数+嵌套函数
# 参考文章:https://www.cnblogs.com/wupeiqi/articles/4980620.html
def time_low(func): # 计算函数运行时间
# 错误装饰器示例
# 此装饰器仅仅适用无传参与无返回值的函数,
# 若对有传参的函数与有返回值的函数使用会出现bug或报错。
# def warpper(): #若函数无参数传入,可以不输入*args, **kwargs,把注释去掉,调用day10_case0()可检验
def warpper(*args, **kwargs):
start_time = time.time()
func()
stop_time = time.time()
print("装饰1:the func run time is %s" % (stop_time - start_time))
return warpper
@time_low
def day10_case0():
# 使用了错误装饰器
print("使用了错误装饰器")
@time_low
def day10_case1(hint="参数传不进来"):
# 使用了错误装饰器
print("使用了错误装饰器")
print(hint)
return hint
def time_new(func): # 计算函数运行时间
# 正确的装饰器示例
# 必须添加*args, **kwargs,否则报错
def warpper(*args, **kwargs):
start_time = time.time()
# 1、必须添加*args, **kwargs,否则被装饰的函数无法传入参数
# 2、可使用一个变量承接函数返回值,若直接return func会返回一个函数的内存地址
# 3、或者最后return func(*args, **kwargs)也可以,不会返回None
func1 = func(*args, **kwargs)
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
# return func # 直接return func会返回一个函数的地址
return func1 # 必须return func函数的返回值,否则被装饰的函数返回值为None
# return func(*args, **kwargs) # 或者return func(*args, **kwargs)也可以
return warpper
# 函数可是看成变量,warpper可以看成变量,若没有调用,即是一堆字符串;
# 例如匿名函数calc = lambda x:x*x; print(calc(10)); 输出100。
# 若函数被调用,会先找到函数的内存地址,然后再运行。
# 函数(装饰器)time_new(func)若被传入值(函数),
# 会运行return warpper,因传入的func使得warpper(*args, **kwargs)变成一个完整函数,
# 然后warpper函数体得以运行,然后再运行func函数体,从而构成一个装饰器
@time_new
def day10_case2(*args):
# 使用了正确装饰器
# 注意:因为*args只传如一个参数,所以传入的实际值为元组(args,)
# 若传入2个参数,传入的实际值为元组(args1,args2)
print("使用了正确装饰器")
print(args)
return args
def day10_case3(*args):
# 高阶函数示例
print("我是函数3")
return args
def day10_case4(args):
# 高阶函数示例
print("我是函数4")
args() # 若args传入函数day10_case3,则运行函数3
return args
def day10_case5():
# 变量内存地址说明
x = 1
y = x
print("x的内存地址为:{0},y的内存地址为:{1}".format(id(x), id(y)))
y = 1
print("因y的值不变,所以x与y的内存地址不变,"
"x的内存地址为:{0},y的内存地址为:{1}".format(id(x), id(y)))
y = 2
print("因y的值改变,y的内存地址改变,x的值不变内存地址不变;"
"x的内存地址为:{0},y的内存地址为:{1}".format(id(x), id(y)))
x = 2
print("因x的值改变,x的内存地址改变,y的内存不变;因x与y的值相等,所以共用地址;"
"x的内存地址为:{0},y的内存地址为:{1}".format(id(x), id(y)))
if __name__ == '__main__':
day10_case_new = time_low_low(day10_case) # 不使用装饰器计算函数运行时间,高阶函数
# day10_case的内存地址将赋值给day10_case_new,time_low_low返回的day10_case是内存地址
day10_case_new() # 加上括号可直接运行day10_case()函数,因为day10_case_new与其共用一个内存地址
# day10_case1()使用了错误装饰器@time_low,参数传不进去,返回值为空
print(day10_case0())
print(day10_case1(hint="case1传入参数"))
# day10_case2()使用了正确装饰器@time_new,参数可传进去,返回值返回正常
print(day10_case2("case2传入参数"))
calc = lambda x: x * x # 匿名函数
print("calc匿名函数结果:", calc(10))
print(day10_case4(day10_case3)) # 高阶函数示例,返回函数3的内存地址
day10_case5() # 变量内存地址说明
2、函数内存地址说明
3、高阶函数
?4、函数day10_case5()运行结果
|