一、nonlocal关键字    作用:将 L 与 E 中的名字统一,L中的名字需要先定义

    应用场景:在被嵌套函数中修改函数外的值

    案例:        def outer():            x = 10            print(x)  # x = 10            def inner():                nonloacl x                x = 20                print(x)  # x = 20

            inner()            print(x)  # x = 20

二、开放封闭原则    1.不能修改被装饰对象(函数)的源代码(封闭)    2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)

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

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

    # 装饰器    def outer(tag):  # tag为被装饰函数的内存地址        def inner():            print(新增功能")            tag()  # 将被被装饰函数的内存地址 传值给tag ,再形成tag()调用原函数        return inner

    fn = outer(fn)  # outer()为函数outer的return值,    fn()  # fn() == inner() 就是 函数outer的ruturn值--函数 inner的内存地址加上()之后 调用

四:语法糖 @外层函数    def outer(f):        def inner():            f()  # 通过参数传递原函数内存地址的方式来调用原函数            print("新增功能1")        return inner

    def wrap(f):        def inner():            f()  # 通过参数传递原函数内存地址的方式来调用原函数            print("新增功能2")        return inner

    @wrap  # 被装饰的顺序决定了新增功能的执行顺序 ==> fn = wrap(fn): inner    @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 = '\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()

转载于:https://www.cnblogs.com/shuchengyi/articles/10642942.html

4.02Day12函数 装饰器相关推荐

  1. python类方法调用装饰_Python3 @classmethod 函数装饰器 声明一个类方法

    Python3 @classmethod 函数装饰器 声明一个类方法 @classmethod函数装饰器的主要作用是将一个类的普通方法(需要实例化使用)声明为一个类方法(可以直接使用类名调用).在类的 ...

  2. Python的神奇功能——函数装饰器MetaClass

    Python中的装饰器,会让很多人望而却步.不要被它吓跑,啃下它,其实超有用,也没有想象中难. 所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改. Python的装饰 ...

  3. python装饰器实例-Python函数装饰器--实例讲解

    一.装饰器定义: 1.装饰器的本质为函数: 2.装饰器是用来完成被修饰函数的附加功能的 所以:装饰器是用来完成被修饰函数附属功能的函数 装饰器的要求: 1.不能修改被修饰函数的源代码: 2.不能更改被 ...

  4. python中的装饰器有哪些-Python中的@函数装饰器到底是什么?

    在解释@函数装饰器之前,先说一下,类中的类方法和静态方法. 在Python中完全支持定义类方法.静态方法.这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以). 区别在于:Pyt ...

  5. python装饰器函数-python装饰器1:函数装饰器详解

    先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础:函数装饰器的表现方式 假如你已经定义了 ...

  6. python装饰器函数-Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所 ...

  7. python装饰器函数-Python函数装饰器指南

    Python 具有强大的功能和富有表现力的语法.我最喜欢的装饰之一.在设计模式的上下文中,装饰器动态更改方法或类功能,而不必直接使用子类.当您需要扩展功能,但不想修改原函数时,这是理想的选择.我们可以 ...

  8. python装饰器-Python @函数装饰器及用法(超级详细)

    前面章节中,我们已经讲解了 Python 内置的 3 种函数装饰器,分别是 @staticmethod.@classmethod 和 @property,其中 staticmethod().class ...

  9. python装饰器原理-Python函数装饰器原理与用法详解

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...

最新文章

  1. python 是什么类型的语言-为什么说 Python 是强类型语言?
  2. linux与开发板串口通信
  3. centos7安装、卸载docker (yum方式)
  4. 用 chown 和 chmod 修改目录所属用户及权限
  5. 机器学习实战(九)树回归
  6. 关于Linq to SQL 的“异常详细信息: System.InvalidCastException: 指定的转换无效。”
  7. express中间件系统的基本实现
  8. Unreal、CryEngine、Gamebryo引擎介绍
  9. 代码审计系列篇一之代码审计学习思路
  10. 安卓10省电还是费电_拍照成罪魁祸首 安卓十大耗电App排行公布
  11. 大话设计模式笔记(十二)の抽象工厂模式
  12. java中 移位运算符_java中的移位运算符心得总结
  13. Lambda将搬砖变成艺术
  14. 个人博客_温州个人博客_Duing-冬忆个人博客
  15. Linux添加SSH Key到Github账户
  16. java如何获取系统的桌面路径
  17. html+css+js+快速入门
  18. 使用LAPS管理本地管理员密码(1)
  19. Xshell7连接VirtualBox虚拟机
  20. 重装系统提示:Windows检测到EFI系统分区格式化为NIFS,将EFI系统分区格式化为FAT3

热门文章

  1. Android的BUG(四) - Android app的卡死问题
  2. SGI STL 学习笔记二 vector
  3. 表的设计命名的十个注意点
  4. Java_方法的调用①及案例
  5. JS中定时器setTimeout,setInterval,clearTimeout,clearInterval用法
  6. C++ 外部函数通过指针修改类成员的值
  7. 建站手册-语义网:语义网
  8. 【week2】 构建之法 读后感及问题
  9. JavaScript对Json的增删改属性
  10. Tomcat的安装及使用