zoukankan      html  css  js  c++  java
  • 函数的重中之重----装饰器

    一、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()

  • 相关阅读:
    Thymeleaf+Spring使用自己的工具类
    bootstrap 响应式布局
    bootstrap 流布局
    bootstrap 布局
    bootstrap 新建网页
    quick 定时更新函数
    acm hdoj 1157
    acm hdoj 今年暑假不ac
    quick removeTileMaptile
    quick schedule 的添加和移除
  • 原文地址:https://www.cnblogs.com/yuanlianghong/p/10657352.html
Copyright © 2011-2022 走看看