闭包函数
什么是闭包函数
闭包即函数内部函数对外部作用域而非全局作用域的引用,说白了就是将函数内部的变量拿到全局来使用,还不会修改局部变量的值
def outter():
x = 5
def inner():
return x
return inner
f = outter()
x = f() + 1
print(f())
print(x)
5
6
两种为函数传参的方式
- 使用参数的形式
def f1(x):
print(x)
f1(1)
f1(2)
f1(5)
1
2
5
- 包给函数
def outter(x):
def inner():
print(x)
return inner
f = outter(1)
f()
f1 = outter(5)
f1()
f()
f1()
1
5
1
5
装饰器
无参装饰器
什么是装饰器
装饰器就是为函数添加额外的功能
注意:
- 装饰器本身其实是可以任意可调用的对象
- 被装饰的对象也可以是任意可调用的对象
装饰器的两大原则
- 不修改被装饰对象的源代码
- 不修改被装饰对象的调用方式
装饰器其实就是遵循以上两大原则的前提下为被装饰对象添加功能
怎样用装饰器
如果我们定义一个函数,需要增加一个计时功能,我们可以使用改变源代码的方式:
import time
def index():
start_time = time.time()
print('睡一秒')
time.sleep(1)
end_time = time.time()
print(end_time - start_time)
index()
睡一秒
1.0007741451263428
但这样就不符合我们装饰器的两大原则了,那我们该怎么来实现呢?
第一种:改变调用方式
import time
def outer(func):
start_time = time.time()
res = func()
end_time = time.time()
print(end_time - start_time)
def index():
print('睡一秒')
time.sleep(1)
outer(index)
睡一秒
1.0006616115570068
第二种:包给函数-外包
import time
def outer(func):
def wrapper():
start_time = time.time()
res = func()
end_time = time.time()
print(end_time - start_time)
return wrapper
def index():
print('睡一秒')
time.sleep(1)
index = outer(index)
index()
睡一秒
1.0004618167877197
完善装饰器
上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),因此如果原始的index()有返回值的时候,wrapper()函数的返回值应该和index()的返回值一样,所以我们需要同步原始的index()和wrapper()方法返回值。
import time
def outer(func):
def wrapper():
start_time = time.time()
res = func()
end_time = time.time()
print(end_time - start_time)
return res
return wrapper
def index():
print('睡一秒')
time.sleep(1)
return '我有返回值'
index = outer(index)
res = index()
print(res)
睡一秒
1.000257968902588
我有返回值
如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可
import time
def outer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print(end_time - start_time)
return res
return wrapper
def index(x):
print('睡一秒')
time.sleep(1)
return f"传入值为:{x}"
index = outer(index)
res = index(5)
print(res)
睡一秒
1.0001804828643799
传入值为:5
装饰器语法糖
import time
def outer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print(end_time - start_time)
return res
return wrapper
@outer # index = outer(index)
def index(x):
print('睡一秒')
time.sleep(1)
return f"传入值为:{x}"
res = index(5)
print(res)
睡一秒
1.0002069473266602
传入值为:5
装饰器模板
def deco(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
@deco
def f1():
pass