一、补充:nonlocal关键字

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

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

3、案例:

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

二、装饰器的原则:

开放封闭原则:不改变调用函数方式与源代码的情况下增加新功能

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

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

三、装饰器

1、原理:

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

2、例:

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、longin有返回值,所以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 = '\033[36;41mnew action\33[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()

八、案例:登入认证功能

is_login = False # 登录状态

def login():
        usr = input('usr: ')
        if not (len(usr) >= 3 and usr.isalpha()):
               print('账号验证失败')
               return False
         pwd = input('pwd: ')
         if usr == 'abc' and pwd =='123qwe':
                 print('登录成功')
                 is_login = True
         else:
                 print('登录失败')
                 is_login = False

# 完成一个登录状态校验的装饰器
def check_login(fn):
          def inner(*args, **kwargs):
# 查看个人主页或销售功能前:如果没有登录先登录,反之可以进入其功能
                  if is_login != True:
                         print('你未登录')
                         login()
# 查看个人主页或销售
                  result = fn(*args, **kwargs)
                  return result
           return inner

# 查看个人主页功能
@check_login
def home():
         print('个人主页')

# 销售功能
@check_login
def sell():
        print('可以销售')

home()

DAY12、装饰器的更多相关文章

  1. day12:装饰器的进阶

    1,三元运算符:变量 = 条件返回True的结果 if 条件 else 条件返回false的结果:必须要有结果:必须要有if和else,只能是简单的情况. 2,传参包起来,星号打散 def outer ...

  2. day12 装饰器的模版

    1.什么是装饰器 装饰器指的是为被装饰对象(别人)添加新功能的工具 装饰器本身可以是任意可调用对象 被装饰器对象也可以是任意可调用对象 2.为何要用装饰器 开放封闭原则:指的是对修改封闭,对扩展开放 ...

  3. 总结day12 ----装饰器

    一,什么是装饰器? 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事 ...

  4. Day12装饰器

    1.装饰器 什么是装饰器:装饰器指的是为被装饰对象添加新功能的工具 装饰器本身可以是任意调用对象 被装饰对象本身也可以是任意可调用对象 2.为何要用装饰器: 开放封闭原则: ①对修改源代码和调用方式是 ...

  5. day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)

    day11:装饰器(装饰器形成.装饰器作用.@语法糖.原则.固定模式) 装饰器形成:最简单的.有返回值的.有一个参数的.万能参数 函数起的作用:装饰器用于在已经完成的函数前后增加功能 语法糖:使代码变 ...

  6. Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)

    一.nonlocal关键字 1.作用:将L与E(E中的名字需要提前定义)的名字统一 2.应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值 def outer(): num=10 print ...

  7. day12 十二、开放封闭、装饰器

    一.nonlocal关键词 # global # num = # def fn(): # global num # L>G 将局部的名字与全局统一 # num = # fn() # print( ...

  8. python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)

    函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...

  9. 函数的有用信息,装饰器 day12

    一 函数的有用信息 本函数的功能:绘图功能,实时接收数据并绘图.:return: 绘图需要的数据,返回给前端某标签 def f1(): ''' 本函数的功能:绘图功能,实时接收数据并绘图. :retu ...

随机推荐

  1. Java开发笔记(二十)一维数组的用法

    之前介绍的各类变量都是单独声明的,倘若要求定义相同类型的一组变量,则需定义许多同类型的变量,显然耗时耗力且不宜维护.为此,编程语言引入了数组的概念,每个数组都由一组相同类型的数据构成,对外有统一的数组 ...

  2. Android开发——使用intent传递对象

    intent传递对象有两种方法: 方式一:Serializable 方式 方式二:Parcelable方式 在这里不多介绍了,这一篇就是快速上手使用教程,至于详细原理介绍的,请看这一篇http://w ...

  3. Fundebug前端JavaScript插件更新至1.7.1,拆分录屏代码,还原部分Script error.

    摘要: BUG监控插件压缩至18K. 1.7.1拆分了录屏代码,BUG监控插件压缩至18K,另外我们还原了部分Script error,帮助用户更方便地Debug.请大家及时更新哈~ 拆分录屏代码 从 ...

  4. Selenium自动化 Xpath-元素定位

    最近在教妹子做自动化测试,妹子基础差,于是想到很多初学自动化的朋友们学习的知识没有规范化,信息太过杂乱.所以,本文整理了一些自动化元素定位方式: 这次将讲Xpath定位! 什么是Xpath: Path ...

  5. [总结]WEB前端开发常用的CSS/CSS3知识点

    css3新单位vw.vh.vmin.vmax vh: 相对于视窗的高度, 视窗被均分为100单位的vh; vw: 相对于视窗的宽度, 视窗被均分为100单位的vw; vmax: 相对于视窗的宽度或高度 ...

  6. 广州.NET微软技术俱乐部 微信群有用信息集锦

    考虑到广州.NET微软技术俱乐部 微信群 十分活跃. 有用信息很有可能被淹没. 所以建立此贴. 首先群的活跃是十分重要的. 所以我是不可能把群搞得像技术论坛和github一样, 因为微信群的定位我在& ...

  7. QT多线程的使用

    今天给大家介绍三种QT里面使用多线程的方法 1.继承QThread并且重写run方法来实现多线程 #ifndef MYQTHREAD_H #define MYQTHREAD_H #include &l ...

  8. USB初学(一)---USB-HID的初步认识【转】

    HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB协议的相关内容. USB设备描述符-概述 当插入USB设备后,主机会向设备请求各种描述符来识别设备.那什么是设 ...

  9. 有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value替换为A中对应的value

    update B b set b.value=(select max(a.value) from A a where b.key=a.key) from A c where b.key=c.key) ...

  10. 三数之和的golang实现

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...