闭包函数与装饰器

闭包函数

 

闭包的由来

 

首先我们需要知道,我们是可以在函数中再定义一个函数的(嵌套函数)。

内部函数含对外部作用域而非全局作用域的引用,

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。

外函数返回了内函数的引用,一个函数,如果函数名后紧跟一对括号,相当于现在我就要调用这个函数,如果不跟括号,相当于只是一个函数的名字,里面存了函数所在位置的引用。
外函数把临时变量绑定给内函数,按照我们正常的认知,一个函数结束的时候,会把自己的临时变量都释放还给内存,之后变量都不存在了。一般情况下,确实是这样的。
但是闭包是一个特别的情况。外部函数发现,自己的临时变量会在将来的内部函数中用到,自己在结束的时候,返回内函数的同时,会把外函数的临时变量送给内函数绑定在一起。
所以外函数已经结束了,调用内函数的时候仍然能够使用外函数的临时变量。

给函数体传参的两种方式:
  1,传参
    def index(username):
      print(username)

 


  2,闭包
    def outter(x,y):
      def my_max():
        if x > y:
          return x
        return y
      return my_max

 

装饰器

复制代码
装饰器:在不修改被装饰对象情况下,给被装饰对象添加新的功能的闭包应用
因为开放封闭原则:
       开放:对扩展开放
       封闭:对修改封闭
装饰器(可调用对象)必须遵循的两个原则:
        1.不改变被装饰对象源代码
        2.不改变被装饰对象(可调用对象)调用方式

装饰器需要先定义再使用
复制代码

装饰器公式

复制代码
装饰器语法糖:会将紧挨着它的可调用对象的名字当做参数自动传入调用outter
@outter
def index():
    pass

1.无参装饰器
    from functools import wraps
    def outter(func):
        @wraps(func)
        def inner(*args,**kwargs):  # * **在形参中使用
            # 执行被装饰函数之前你可以做的操作
            res = func(*args,**kwargs)  # * **在实参中使用
            # 执行被装饰函数之后你可以做到操作
            return res
        return inner

    @outter
    def index(username,*args,**kwargs):
        """index注释"""
        pass
    print(index)

    装饰器修复技术

        1.返回原来的函数的函数名
        2.返回原来的函数的注释

2.有参装饰器(最复杂就三层)
def wrappers(data):
    # data = 'file'
    def outter(func):
        def inner(*args,**kwargs):
            if data == 'file':
                # 执行被装饰函数之前你可以做的操作
                res = func(*args,**kwargs)  # * **在实参中使用
                # 执行被装饰函数之后你可以做到操作
                return res
        return inner
    return outter
 
posted @ 2019-07-11 17:55  小肥海  阅读(112)  评论(0编辑  收藏  举报