闭包 : 一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了
def outer(x):
def inner(y):
return x * y
return inner
print(outer(2)(4))
上面的代码所示,在outer函数内,又定义了inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了,在输入时,outer(2)(4),第一个括号传进去的值返回inner函数,其实就是返回2*y,所有再传递第二个参数进去,就可以得到返回值。
装饰器实着呢就是闭包的一种应用。什么是装饰器呢? - 简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上 @ 即可
def cost_time1(_func):
def func():
start_time = time.perf_counter()
_func()
print('{} cost at {}s'.format(_func ,time.perf_counter()-start_time))
return func
# 装饰器接受到的第一个参数为下面的 函数名 及 print_odds1 传入 cost_time1再调用的一个过程
@cost_time1
def print_odds1():
"""
输出 1~100之间所有奇数,并计算函数的时间开销
"""
for i in range(101):
if i % 2 == 1:
print(i, end=' ')
函数带参数的装饰器
def cost_time3(_func):
def func(*args, **kwargs):
start_time = time.perf_counter()
ret = _func(*args, **kwargs)
print('{} cost at {}s'.format(_func ,time.perf_counter()-start_time))
return ret
return func
@cost_time3
def print_odds3(n):
"""
返回 1~n 之间所有奇数,并计算函数的时间开销
"""
res = []
for i in range(n+1):
if i % 2 == 1:
res.append(i)
return res
类装饰器
还记得前面所学的魔术方法 call。这里所使用的主要就是它了,用法与函数装饰器并没有太大区别
import time
class Auxiliary:
def __init__(self, func):
self.start_time = time.perf_counter()
self.func = func
def __call__(self, *args, **kwargs):
res = self.func(*args, **kwargs)
print('{} cost at {}s'.format(self.func ,time.perf_counter()-self.start_time))
return res
@Auxiliary
def print_odds3(n):
"""
返回 1~n 之间所有奇数,并计算函数的时间开销
"""
res = []
for i in range(n+1):
if i % 2 == 1:
res.append(i)
return res
当然了,装饰器也是可以带参数的,如下实现
def a(sex):
def b(func):
def c():
if sex =='man':
print('不可以生孩子')
if sex =='woman':
print('可以生孩子')
return func()
return c
return b
# 增加功能, man: 打印 不可以生孩子
# woman: 打印 不可以生孩子
@a(sex='man')
def man():
print('努力工作')
@a(sex='woman')
def woman():
print('努力工作')