zoukankan      html  css  js  c++  java
  • DAY12 装饰器

    一.nonlocal关键字

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

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

    ​ 3.案例:

    ​ def outer()

    ​ num = 10

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

    二.开放封闭原则

    ​ 1.定义:不改变调用方式与源代码前提下增加功能

    ​ 2.要求:

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

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

    三.装饰器

    ​ 定义:把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数

    ​ def fn():

    ​ print("原有功能")

    ​ 装饰器:

    ​ def outer(func):

    ​ def inner():

    ​ func() # 原有的功能fn()

    ​ print('新增功能')

    ​ return inner # 拓展功能后的fn

    ​ fn = outer(fn) # 将拓展功能后的功能函数重新赋值给fn

    ​ fn()

    ​ 1.被装饰的函数:fn

    ​ 2.外层函数:outer(func) outer(fn) ==> func = fn

    ​ 3.替代版函数:return inner :原功能+新功能

    四.@语法糖

    ​ python中装饰器 fn = outer(fn)可以中@outer来代替其中@后跟的是外层函数

    ​ def outer(func):

    ​ def inner():

    ​ func() # 原有的功能fn()

    ​ print('新增功能')

    ​ return inner # 拓展功能后的fn

    ​ def warp(func):

    ​ def inner():

    ​ func() # 原有的功能fn()

    ​ print('新增功能')

    ​ return inner # 拓展功能后的fn

    ​ @warp # 被装饰的顺序决定了新增功能的执行顺序

    ​ @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都有返回值

    六.装饰器最终

    ​ 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()
  • 相关阅读:
    为什么一刷新页面session没了
    Dedecmsv5.7整合ueditor 图片上传添加水印
    DedecmsV5.7本地上传缩略图无法自动添加水印的解决方法
    mysql find_in_set()函数的使用
    利用phpqrcode二维码生成类库和imagecopymerge函数制拼接图片的经验
    dedecms自定义表单时间时间戳值类型的转换方法
    jquery 根据自定义属性选择
    jquery快速获得url 的get传值
    自定义Bean初始化和销毁方法
    Spring常用注解
  • 原文地址:https://www.cnblogs.com/majingjie/p/10642879.html
Copyright © 2011-2022 走看看