在函数内部定义一个内嵌函数,内嵌函数引用外部函数的变量并且作为外部函数的返回值返回。
创建一个闭包需要满足以下几点:
def user(name):
def introduce():
print('大家好,我叫{}'.format(name))
return introduce
user1 = user('杨过')
user1() # 大家好,我叫杨过
user2 = user('小龙女')
user2() # 大家好,我叫小龙女
闭包的最大特点是可以将函数的变量与内嵌函数进行绑定,并返回绑定变量后的内嵌函数,此时即便生成闭包的环境已经释放,内嵌函数仍然存在。
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(10) # 定义10个线程的线程池
def func1(i):
'''定义执行函数,返回值为i'''
print(str(i).center(5, '-'))
return i
def outer(i):
'''定义闭包'''
def func2(func):
'''会调函数打印函数执行结果及将传入参数格式化'''
print(func.result(), str(i).center(5, '*'))
return func2
def run():
for i in range(30):
f = pool.submit(func1, i)
cb = outer(i)
f.add_done_callback(cb)
pool.shutdown(wait=True)
if __name__ == '__main__':
run()
实质上也是一个闭包,闭包传递的是变量,而装饰器传递的是函数,也就是说,装饰器是一个传递函数的闭包。
打印【0,num】并计算函数执行时间
import time
def decorator(func):
def runtime(num):
time_begin = time.time()
func(num)
print('函数{}执行耗时{}秒。'.format(func.__name__, round(time.time() - time_begin, 4)))
return runtime
@decorator
def run(num):
for i in range(num):
print(i)
run(100)
import time
def decorator(func):
"""装饰器"""
def runtime(num):
time_start = time.time()
sum = func(num)
print('函数{}运行时长:{}秒。'.format(func.__name__, round(time.time() - time_start, 6)))
return sum
return runtime
@decorator
def run(num):
sum = 0
for i in range(num):
sum += i
return sum
print(run(10000000))
# 函数run运行时长:0.530971秒。
# 49999995000000
在不改变原函数的情况下,对已有函数进行额外的功能扩展,示例就展示了在不改变函数run的情况下输出run运行时间。
在装饰器外再包含一层即可实现带参数的装饰器。
import time
def decorator(num):
"""带参数的装饰器"""
def outer(func):
def runtime(*args):
print('Before:')
time_start = time.time()
sum = func(*args)
print('{}.函数{}运行时长:{}秒。'.format(num,func.__name__, round(time.time() - time_start, 6)))
return sum + args[0]
return runtime
return outer
@decorator(100)
def run(*args):
sum = 0
for i in range(args[0]):
sum += i
return sum
print(run(100))
# Before:
# 100.函数run运行时长:0.0秒。
# 5050