python---闭包和装饰器

1、参考博客:https://www.cnblogs.com/3me-linux/p/6761635.html

2、闭包:外层函数套用内层函数,返回内层函数。返回的内层函数在被调用时,记住定义时的位置

def outer():
     x = 1
     def inner():
         print x # 1
     return inner
foo = outer()
foo.func_closure # doctest: +ELLIPSIS
(<cell at 0x: int object at 0x>,)
foo() 
1

变量作用域:python的作用域规则下进行工作:“x是函数outer里的一个局部变量。当函数inner在#1处打印x的时候,python解释器会在inner内部查找相应的变量,当然会找不到,所以接着会到封闭作用域里面查找,并且会找到匹配。

变量生命周期:我们的变量x是函数outer的一个本地变量,这意味着只有当函数outer正在运行的时候才会存在。根据我们已知的python运行模式,我们没法在函数outer返回之后继续调用函数inner,在函数inner被调用的时候,变量x早已不复存在,可能会发生一个运行时错误。然而,它可以正常工作

闭包:Python支持一个叫做函数闭包的特性,嵌套定义在非全局作用域里面的函数能够记住它在被定义的时候它所处的封闭命名空间。这能够通过查看函数的func_closure属性得出结论,这个属性里面包含封闭作用域里面的值(只会包含被捕捉到的值,比如x,如果在outer里面还定义了其他的值,封闭作用域里面是不会有的)。。。。。

3、装饰器:装饰器本质就是一个闭包,对原函数进行装饰。外层函数传入函数名,内层函数传入函数的参数


def add(a,b):
return a+b


我们知道以上加法,对输入的参数是没有做校验的,那么如何在不改变函数本身的情况下,给add函数增加功能呢????

装饰器就可以完成以上要求

def valid(func):  #外层传入函数名
    def test(a,b):  #内层传入函数的参数,对于参数较多的情况*args,**kargs是较好的写入方式
        try:
            _a = float(a)
        except ValueError as error:
            print(error)
        try:
            _b = float(b)
        except ValueError as error:
            print(error)
        return print(func(_a,_b))  #引入函数
    return test

def add(a,b):
    return a+b

valid(add)('0.2',3)
控制台输出:3.2

如何更简单的使用呢

def valid(func):
    def test(a,b):
        try:
            _a = float(a)
        except ValueError as error:
            print(error)
        try:
            _b = float(b)
        except ValueError as error:
            print(error)
        return print(func(_a,_b))
    return test

@valid  #此部分,相当于add = valid(add)
def add(a,b):
    return a+b

add('0.2',3)  

4、装饰器的常用场景

  引入日志、函数执行时间统计、执行函数前预处理、执行函数后清理功能、权限校验、缓存、事务处理、性能测试等

原文地址:https://www.cnblogs.com/hzgq/p/11770315.html