一.闭包函数
就是在函数的内部再定义一个函数,并且该函数包含对外部函数作用域的名字的引用
def outter(x):#这里x为形参
# x=1 #这里可以给x赋值,但是x就固定死了
def inner():
print(x)
return inner
f = outter(10)# 调用outter函数,得到返回值inner 然后赋值给f,就是f = inner
f()
#inner就是一个闭包函数
注意:闭包函数的作用域在定义阶段就固定死了,与调用位置无关.
二.装饰器
1.开发封闭原则
当软件上线后,必须遵循开发封闭原则:
1.1对源代码是封闭的
1.2对功能的拓展是开放的
但是如果需要添加新功能,那该如何解决呢?
这就需要装饰器了,首先装饰器必须遵循以下两点:
2.1不能修改源代码
2.2不能修改对函数的调用方式
在遵循以上两点的情况下还可以拓展新功能
所以装饰器就是在不修改被装饰对象的源代码和其调用方式的前提下,能够为其添加新功能
装饰器和被装饰对象是可以任意调用的对象
装饰器的固定模式:
def outter(func):
def inner(*args,**kwargs):
#代码块
res = func(*args,**args)
return res
retunrn inner
这是装饰器的固定格式
例子:
import time
def index():
time.sleep(3)#模仿网页,执行下一句代码之前睡3秒
print('from index')
return
def outter(func):# 2.func=index
def inner(*args,**kwargs):# 4.调用inner()
start_time=time.time()# 5.记录开始时间
res = func(*args,**kwargs)#res=index()# 6.调用最原始的index,执行sleep,然后print
end_time=time.time()# 7.记录结束时间
print('run time is %s'%(end_time-start_time))# 8.将调用index使用的时间打印出来
return res# 9.返回最原始的index的返回值
resturn inner
index=outter(index)# 此时第一个的index已经被覆盖了,是一个新的index
# 1.执行这一步是将原始的index当作outter的实参传入,然后得到返回值inner
#即index = inner
f = index()
# 3.执行这一步即index()=inner()
#调用inner(),得到返回值res
#即调用最原始的index函数中的代码块,进行print()和返回值
print(f) #10.即将原始的index()的返回值打印到屏幕
其中index()是源代码,outter()是装饰器
此时可以使用装饰器的语法糖
import time
def outter(func):
def inner(*args,**kwargs):
start_time=time.time()
res = func(*args,**kwargs)
end_time=time.time()
print('run time is %s'%(end_time-start_time))
resturn inner
@outter# 等同于 index=outter(index)
def index():
time.sleep(3)
print('from index')
return
index()
语法糖:装饰器必须写在被装饰对象的上面.然后在被装饰对象上面一行写上 @+装饰器
以上是无参装饰器的内容