我们首先了解下什么是闭包
在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
闭包 = 内部函数 + 定义函数时的环境
def outer():
a = 8
def inner(): # 条件一: inner就是内部函数
print(a) # 条件二: 外部环境的一个变量
return inner # 结论:内部函数 inner 就是一个闭包
f = outer()
f()
运行结果:
8
装饰器
import time
def foo():
print('foo....')
time.sleep(2)
def bar():
print('bar....')
time.sleep(2)
def show_time(func):
def inner():
start = time.time()
func()
end = time.time()
print('spend %s' % (end - start))
return inner
foo = show_time(foo)
foo()
运行结果:
foo....
spend 2.0003552436828613
@符号是 python 装饰器的语法,在定义函数的时候使用,避免再一次赋值操作
import time
def show_time(func):
def inner():
start = time.time()
func()
end = time.time()
print('spend %s' % (end - start))
return inner
@show_time # bar = show_time(bar)
def bar():
print('bar....')
time.sleep(2)
bar()
运行结果:
bar....
spend 2.0004019737243652
执行 bar 函数实际上是执行 inner 函数的内容
带有未命名的变量参数的装饰器
import time
def show_time(func):
def inner(*args):
start = time.time()
func(*args)
end = time.time()
print('spend %s' % (end - start))
return inner
@show_time
def add(*args):
sums = 0
for i in args:
sums += i
print(sums)
time.sleep(2)
add(1, 2, 3, 4, 5)
运行结果:
15
spend 2.0084943771362305
功能函数带参数
import time
def logger(flag): # 把 flag 传入 inner 函数中
def show_time(func):
def inner(*args):
start = time.time()
func(*args)
end = time.time()
print('spend %s' % (end - start))
if flag == 'true':
print("write log ....")
return inner
return show_time
@logger('true') # 这里调用 logger 函数 return show_time 实际上是调用了 @show_time
def add(*args):
sums = 0
for i in args:
sums += i
print(sums)
time.sleep(2)
add(1, 2, 3, 4, 5)
运行结果:
15
spend 2.000865936279297
write log ....