• 闭包&装饰器


    1.闭包&装饰器

    1.1 闭包

    关于函数:

    • 当python遇到 def 语句时候 ,会在内存中生成一个函数对象,并且这个函数是靠将函数名来引用,但是这个函数体内部的语句只有在函数的调用的时候才会被执行,而函数调用结束了,就是函数返回时,函数执行完后内部变量将会被回收  
    • 函数是一个对象,所以可以以对象的形式作为某个函数的结果返回,

    闭包:

    • 简单来说,外层函数outer()里面包含了一个内部函数 inner(),并且外部函数返回内部函数的对象
      def outer():
          name = "alex"
          # 内部函数
          def inner():
              print(name)
          return inner
      fn = outer()         # 访问外部函数, 获取到内部函数的函数地址
      fn()                 # 访问内部函数
    • 内部函数inner() 存在对外部函数outer()的引用 ,此时这个内部函数 inner()就叫做闭包
    • 在闭包中,由于内部函数存在对外部函数变量的引用,所以即使外部函数执行完毕,该变量依然存在但是一定是内层函数调用的外层函数的变量,如果内层函数不会引用,那么这个变量也是不存在的

    1.2 装饰器

    1.2.1 装饰器的作用

    • 装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,
    • 装饰器的返回值也是一个函数/类对象。
    • 它有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用
    1.2.2不带参数的装饰器
     
    (1)无参数无返回值的函数
    def timer(func):
        def inner():
            print('-函数前添加功能-')
            func()
            print('- 函数后添加功能-')
        return inner
    
    #定义一个函数,并添加装饰器
    @timer   #等价于  func1 = timer(func1)
    def func1():
        print('func1')

    #函数执行结果

     # -函数前添加功能-
     # func1
     # -函数后添加功能-

    (2)有参数有返回值的函数

    def wrapper(func):
        def inner(*args,**kwargs):
            print('--函数前添加功能--')
            ret = func(*args,**kwargs)
            print('--函数后添加功能--')
            return ret
        return inner
    
    #定义一个函数,并添加装饰器
    @wrapper   #等价于  func1 = timer(func1)
    def func1(m):
        print('--func1--')
        return m
    #调用函数
    f = func1(20)
    print(f)

     1.2.3 带有参数的装饰器

    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print('--添加功能--')
                    ret = func(*args,**kwargs)
                else:
                    ret = func(*args,**kwargs)
                return ret
            return inner
        return timer
    #定义函数并添加装饰器
    @outer(True)  # func1 = timer()
    def func1(m):
        print('--func1--')
        return m
    #调用函数
    print(func1(20))

      #--添加功能--
      #--func1--
      #20

    1.2.4 多个装饰器装饰一个函数

    def wrapper1(func):
        print('--wrapper1装饰--')
        def inner1(*args,**kwargs):
            print('--wrapper1 前--')
            ret = func(*args,**kwargs)
            print('--wrapper1 后--')
            return ret
        return inner1
    
    def wrapper2(func):
        print('--wrapper2装饰--')
        def inner2(*args,**kwargs):
            print('--wrapper2 前--')
            ret = func(*args,**kwargs)
            print('--wrapper2 后--')
            return ret
        return inner2
    
    #定义函数并添加装饰器
    @wrapper2   #func1 = wrapper2(func1)  inner2  func = inner1
    @wrapper1   #func1 = wrapper1(func1)  inner1  func = func1
    def func1(m):
        print ('--func1--')
        return m
    #调用函数
    print(func1(20))
    
    #执行结果:
    # --开始装饰wrapper1--
    # --开始装饰wrapper2--
    # --wrapper2 前--
    # --wrapper1 前--
    # --func1--
    # --wrapper1 后--
    # --wrapper2 后--
    # 20

    #注:

    • 装饰器在代码写完后,此时不用调用函数,就会进行装饰
    • 函数装饰时,会先执行离函数最近的装饰器
    • 当调用函数时,函数会先执行离函数最远的装饰器再执行离的近的装饰器,再执行函数本身

    1.2.5 装饰器修复技术

    import time
    from functools import wraps
    def timer(func):
        @wraps(func)
        def inner():
            print(time.time())
            ret = func()
            return ret
        return inner

     另外:可以通过functools使得打印名字为函数原本名

    import functools
    def wrapper(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            return func(*args, **kwargs)
    
        return inner
    
    
    @wrapper
    def f1():
        print('f1')
    
    
    @wrapper
    def f2():
        print('f1')
    
    print(f1.__name__)
    print(f2.__name__)
  • 相关阅读:
    拖拽 上传文件
    复制文本消息
    zTree 显示为‘aa’,当选择aa时,传的参数为‘22’
    移动端 动画 启动硬件加速
    jquery 停止动画与切换
    CSS小技巧-怎样让每行多余的文字显示文省略号?
    CSS小技巧-两个盒子之间的间距问题
    CSS小技巧-为内盒子添加margin-top时,会带着父盒子一起下来,如何解决?
    小K的H5之旅-CSS基础(一)
    小K的H5之旅-HTML的基本结构与基本标签
  • 原文地址:https://www.cnblogs.com/wcx666/p/10065313.html
Copyright © 2020-2023  润新知