一、装饰器:
本质:就是函数,功能:为其他函数添加附加功能
二、原则:
1、不修改被修饰函数的源代码(开放封闭原则)
2、不修改被修饰函数的调用方式
# 例子 1
# 统计1-100数字求和,所用的时间
import time
def cal(l):
start_time=time.time()
res=0
for i in l:
res+=i
stop_time=time.time()
print("运行时间:%s" %(stop_time-start_time))
return res
print(cal(range(100)))
三、装饰器的知识储蓄:装饰器=高阶函数+函数嵌套+闭包
# 1、装饰器例子:一个计算函数运行时间的装饰器:
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print("函数运行时间:%s"%(stop_time-start_time))
return res
return wrapper
# 给下列程序添加一个装饰器,计算程序运行时间:
@timer
def cal(l):
res=0
for i in l:
time.sleep(0.1)
res+=i
return res
print(cal(range(10)))
a.高阶函数:
1)函数接受的参数是一个函数名;
2)函数的返回值是一个函数名;
3、满足上述条件任意一个,都可以称之为高阶函数。
# 多运行了一次,单靠高阶函数 无法满足装饰器功能
import time
def foo():
time.sleep(2)
print("from the foo")
def timer(func):
start_time=time.time()
func()
end_time=time.time()
print("函数运行时间 %s" %(start_time-end_time))
return func
foo=timer(foo)
foo()
# 多运行了一次,单靠高阶函数 无法满足装饰器功能
高阶函数总结
(1).函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
(2).函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
b.闭包
# 函数嵌套:函数中定义一个函数
def father(name):
print('from father %s' %name)
def son():
print('from son')
print(locals())
# locals() 调用当前层局部变量 结果:{'name': '初相识', 'son': <function father.<locals>.son at 0x0000000002811488>}
father('初相识')
# 闭包:闭-封装变量 下面:1、2、3 分别是一个闭包
'''
闭包:在一个作用域里放入定义变量,相当于打了一个包
'''
def father(name): #3
def son(): # 2 #3
print('我爸爸是 [%s]' %name) # 2 #3
def grandson(): # 1 # 2 #3
print('我爷爷是 [%s]' %name) # 1 # 2 #3
grandson() # 2 #3
son() #3
father('初相识')