• 函数的重中之重----装饰器


    一、nonlocal关键字

          # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一

          # 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值

          # 案例:

                def outer():
                  num = 10
                  print(num)    # 10

                  def inner():
                    nonlocal num
                    num = 20
                      p77rint(num)   # 20
                  inner()
                  print(num)     # 20

    二、开放封闭原则:不改变调用方式与源代码上增加功能

          1.不能修改被装饰对象(函数)的源代码(封闭)

          2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)

    三、装饰器

        # 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
        # 被装饰的函数:fn
        # 外层函数:outer(func) outer(fn) => func = fn
        # 替代版函数: return inner: 原功能+新功能

            def fn():
              print("原有功能")

            # 装饰器
            def outer(tag):
              def inner():
                tag()
                print(新增功能")
            return inner
            fn = outer(fn)
            fn()

    四、@语法糖: @外层函数

            def outer(f):
              def inner():
                f()
                print("新增功能1")
              return inner

            def wrap(f):
              def inner():
                f()
                print("新增功能2")
              return inner

           @wrap # 被装饰的顺序决定了新增功能的执行顺序
            @outer # <==> fn = outer(fn): inner
            def fn():
              print("原有功能")

    五、有参有返的函数被装饰

          def check_usr(fn): # fn, login, inner:不同状态下的login,所以参数是统一的
            def inner(usr, pwd):
              # 在原功能上添加新功能
              if not (len(usr) >= 3 and usr.isalpha()):
                print('账号验证失败')
                return False

              # 原有功能
              result = fn(usr, pwd)

              # 在原功能下添加新功能
                return result
              return inner


              @check_usr
              def login(usr, pwd):
                if usr == 'abc' and pwd =='123qwe':
                  print('登录成功')
                  return True
                print('登录失败')
                return False

    # 总结:
    # 1.login有参数,所以inner与fn都有相同参数
    # 2.login有返回值,所以inner与fn都有返回值

    """
    inner(usr, pwd):
    res = fn(usr, pwd) # 原login的返回值
    return res


    login = check_usr(login) = inner

    res = login('abc', '123qwe') # inner的返回值

    六、装饰器最终写法

            def wrap(fn):
              def inner(*args, **kwargs):
                print('前增功能')
                result = fn(*args, **kwargs)
                print('后增功能')
                return result
              return inner

            @wrap
            def fn1():
              print('fn1的原有功能')
            @wrap
            def fn2(a, b):
              print('fn2的原有功能')
            @wrap
            def fn3():
              print('fn3的原有功能')
              return True
            @wrap
            def fn4(a, *, x):
              print('fn4的原有功能')
              return True

            fn1()
            fn2(10, 20)
            fn3()
            fn4(10, x=20)

    七、带参装饰器:了解

            # 了解
            def outer(input_color):
              def wrap(fn):
                if input_color == 'red':
                  info = '33[36;41mnew action33[0m'
                else:
                  info = 'yellow:new action'

                def inner(*args, **kwargs):
                  pass
                  result = fn(*args, **kwargs)
                  print(info)
                  return result
                return inner
              return wrap # outer(color) => wrap


            color = input('color: ')
            @outer(color)               # @outer(color) ==> @wrap # func => inner
            def func():
              print('func run')

            func()

  • 相关阅读:
    golang pprof 使用
    iostat相关参数说明——await:平均每次设备I/O操作的等待时间 (毫秒),如果%util接近 100%,说明产生的I/O请求太多...
    二分查找
    golang 切片copy复制和等号复制的区别
    维生素
    LinkedBlockingQueue
    ArrayBlockingQueue
    wordpress文章点击次数统计插件WP Postviews 使用方法
    windows7下cmd窗口使用ssh登录服务器(云、本地)
    WinISO Standard V6.4.1.6137 免费无限制版
  • 原文地址:https://www.cnblogs.com/yuanlianghong/p/10657352.html
Copyright © 2020-2023  润新知