# 一、闭包

  闭包是指在外部函数中再嵌套一个内部函数,并且内部函数引用外部函数的变量。

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
更新于 阅读次数