# 一、闭包
闭包是指在外部函数中再嵌套一个内部函数,并且内部函数引用外部函数的变量。
def outer(x): | |
def inner(y): | |
return x + y | |
return inner | |
print(outer(6)(5)) | |
----------------------------- | |
>>>11 |
如代码所示,在 outer
函数内,又定义了一个 inner
函数,并且 inner
函数又引用了外部函数 outer
的变量 x
,这就是一个闭包了。在输出时, outer(6)(5)
, 第一个括号传进去的值返回 inner
函数,其实就是返回 6 + y
,所以再传第二个参数进去,就可以得到返回值, 6 + 5
。
# 二、装饰器
装饰器是闭包的一种应用。 python
装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用 python
装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上 @demo
即可。
from time import time | |
def timer(func): | |
def func_wrapper(*args, **kwargs): | |
time_start = time() | |
result = func(*args, **kwargs) | |
time_end = time() | |
time_spend = time_end - time_start | |
print('\n{0} cost time {1} s\n'.format(func.__name__, time_spend)) | |
return result | |
return func_wrapper | |
@timer | |
def example(): | |
print("hello world!") | |
# 相当于 | |
# example = timer(example) | |
# example() | |
example() | |
----------------------------- | |
>>>hello world! | |
>>> | |
>>>example cost time 0.0 s |
# 三、装饰器带参数
现在如果有多个函数都可以加上 @timer
来看函数的执行时间了,如果想对其中部分函数除了看函数的执行时间外,还想执行的时候写入日志。这时候就需要给装饰器函数入参了。
from time import time | |
def logger(flag): | |
def timer(func): | |
def func_wrapper(*args, **kwargs): | |
time_start = time() | |
result = func(*args, **kwargs) | |
time_end = time() | |
time_spend = time_end - time_start | |
print('{0} cost time {1} s'.format(func.__name__, time_spend)) | |
if flag: | |
print('写入日志') | |
return result | |
return func_wrapper | |
return timer | |
@logger(True) | |
def example1(): | |
print("hello world!") | |
@logger(False) | |
def example2(): | |
print("hello world!") | |
example1() | |
print('**********') | |
example2() | |
------------------ | |
>>>hello world! | |
>>>example1 cost time 0.0 s | |
>>>写入日志 | |
>>>********** | |
>>>hello world! | |
>>>example2 cost time 0.0 s |
# 四、类装饰器
装饰器也不一定只能用函数来写,也可以使用类装饰器,用法与函数装饰器并没有太大区别,实质是使用了类方法中的 call
魔法方法来实现类的直接调用。
class logging(object): | |
def __init__(self, func): | |
self.func = func | |
def __call__(self, *args, **kwargs): | |
print("[DEBUG]: enter {}()".format(self.func.__name__)) | |
return self.func(*args, **kwargs) | |
@logging | |
def hello(a, b, c): | |
print(a, b, c) | |
hello("hello,","good","morning") | |
----------------------------- | |
>>>[DEBUG]: enter hello() | |
>>>hello, good morning |