闭包函数与装饰器

一、闭包函数

定义在函数内部的函数,并且该函数包含对外部函数作用域中名字的引用,该函数就称为闭包函数。
一个持有外部环境变量的函数就是闭包,闭包=函数块+定义函数时的环境。
闭包函数是一个能记住嵌套作用域变量值的函数,尽管作用域已经不存在

工厂函数定义了一个外部的函数,这个函数简单的生成并返回一个内嵌的函数,仅仅是返回却不调用,因此通过调用这个工厂函数,可以得到内嵌函数的一个引用,内嵌函数就是通过调用工厂函数时,运行内部的def语句而创建的。

 

闭包的作用:
1、当闭包执行完后,仍然能够保持住当前的运行环境。希望函数的每次执行结果,都是基于这个函数上次的运行结果。
2、闭包可以根据外部作用域的局部变量来得到不同的结果。这有点像一种类似配置功能的作用,可以修改外部的变量,闭包根据这个变量展现出不同的功能。比如有时需要对某些文件的特殊行进行分析,先要提取出这些特殊行。

 

闭包中是不能修改外部作用域的局部变量的,作用域关系在函数定义阶段就规定死了,与调用位置无关。

 

二、装饰器

装饰器其实就是一个闭包函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问。

装饰器与被装饰对象均是可以任意可调用的对象,可以是函数

 

装饰器的作用:

在不修改被装饰对象源代码与调用方式前提下,为被装饰对象添加新功能

 

一般情况下,装饰器主要可以用在缓存、日志、URL路由和权限校验等常见的功能上
1)、缓存:假设有一个函数的运行时间比较长,为了节省时间,我们可以对其结果进行缓存
2)、单例模式的优雅实现
3)、线程装饰器实现简单异步:将被装饰的函数进行异步处理,耗时的操作将在新线程中运行,web服务可以直接返回响应,无需等待
4)、失败重试机制:利用装饰器,对某些函数增加重试功能

 

装饰器基本形式模板:

def outter(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

 

语法糖:@放在被装饰对象的正上方

叠加多个装饰器:
@
@
被装饰对象

 

当有多个装饰器时,装饰顺序按靠近被装饰对象顺序执行。调用时由外而内,执行顺序和装饰顺序相反

 

在装饰器中,被装饰函数的元属性变成了装饰函数(装饰器最终返回的那个函数)的信息,为了消除这种副作用,可以使用functools模块的wraps方法,对装饰器最终返回的那个函数进行装饰

模板:
from functools import wraps

def outter(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

 

posted @ 2018-06-05 19:00  字符编码  阅读(127)  评论(0编辑  收藏  举报