装饰器
1、闭包
(1) 什么是闭包?
在函数中再嵌套一个函数,并且引用外部封闭函数的变量,外部封闭函数返回内部嵌套函数,这就是一个闭包。
def outer(x):
print("x: ", x)
def inner(y):
print("y: ", y)
return x + y
return inner
print(outer(6)(5))
# 运行结果:
x: 6
y: 5
11
2、装饰器
装饰器是闭包的一种应用。
什么是装饰器呢?简而言之,python装饰器就是用于扩展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码的前提下给函数增加新的功能。
使用:在需要的函数前加上 @demo 即可。
# 编写一个记录函数耗时的装饰器
import time
def log_time(func): # 接收一个函数作为参数
def log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
print("use time: {}".format(time.time() - beg))
return res
return log
@log_time # @: 装饰器语法糖
def mysleep():
time.sleep(1)
mysleep()
# 等价于
mysleep = log_time(mysleep)
mysleep()
# 运行结果:
use time: 1.0006766319274902
3、带参数的装饰器
# 带参数的装饰器
def logging(name): # 参数
def log_time(func): # 接收一个函数作为参数
def log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
print("{} use time: {}".format(name, time.time() - beg))
return res
return log
return log_time
@logging(name="麻花") # @: 装饰器语法糖
def mysleep():
time.sleep(1)
mysleep()
# 运行结果:
麻花 use time: 1.000929594039917
4、类装饰器
类装饰器实质上是使用了类方法中的 __call__ 魔术方法来实现类的直接调用。
# 类装饰器
class LogTime():
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
beg = time.time()
res = self.func(*args, **kwargs)
print("use time: {}".format(time.time() - beg))
return res
@LogTime # @: 装饰器语法糖
def mysleep():
time.sleep(1)
mysleep()
# 运行结果:
use time: 1.00093412399292
5、带参数的类装饰器
# 带参数的类装饰器
class LogTime():
def __init__(self, name):
self.name = name
def __call__(self, func):
def log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
print("{} use time: {}".format(self.name, time.time() - beg))
return res
return log
@LogTime(name="米线") # @: 装饰器语法糖
def mysleep():
time.sleep(1)
# 运行结果:
米线 use time: 1.0000083446502686