在上一篇博文的经典案例中,我想你应该对装饰器有很好的了解了,不过光有那些还不够真的,还需要总结和进阶一下,所以本篇博文解析装饰器进阶。

装饰器

1.什么是装饰器?

个人理解:装饰器又叫语法糖,指的是对原程序内部整个代码不作任何更改,在外部写好一个带某种功能的程序来作用于原程序,对其进行修饰或者叫装饰,这就是装饰器。

还有两种理解是:

1).在代码运行期间动态增加功能的方式,称之为“装饰器”

2).装饰器,允许向一个现有的对象添加新的功能,同时又不改变其结构。作为现有对象的一个包装

2.格式:

def func():
  suite
@func
def func1():
  suite

@func即表示装饰器,这个写法等价于func=func(func1)

例子:

一般用法:

使用装饰器:

是的,你发现了,其实两个写法得到的结果是一样的。所以印证前面那句话,是等价的

即:等价于:

4.装饰器的作用:

1).装饰器可以极大的简化代码,避免每个函数编写重复性代码

2).装饰器在实际的开发中很实用,不需要修改原代码,直接对其进行重新扩展功能即可

3).装饰器遵循封闭开放原则。

  • 封闭:已实现的功能代码块
  • 开放:对扩展开发

5.装饰器内装饰的函数一样可以传入参数:

外层函数传入的是函数对象作为参数,内层函数传入的是外层函数的传入的函数的参数作为参数,听起来有点拗口,集合看上面的例子看你就懂了

6.一个函数可以被多个装饰器装饰

def outer1(func):
    def inner(*args,**kwargs):
        print("认证成功!")
        return func(*args,**kwargs)
    return inner
def outer2(func):
    def inner(*args,**kwargs):
        print("开始解决第一个项目问题")
        return func(*args,**kwargs)
    return inner

def outer3(func):
    def inner(*args,**kwargs):
        print('开始解决第二个项目问题')
        return func(*args,**kwargs)
    return inner

@outer1
@outer2
@outer3
def bumen1(name,age):
    print("%s 正在连接部门1数据接口......"%name)

bumen1("yang",21)

结果:

 7.装饰器自身也可以带参数

1).装饰器带参数,函数不带:

def out(arg):
    def inner1(func):
        def inner2():
            print("before %s called [%s]." % (func.__name__, arg))
            func()
            print("after %s called [%s]." % (func.__name__, arg))

        return inner2
    return inner1
@out("module2")
def myfunc():
    print("myfunc() called.")

myfunc()

结果:

2).装饰器和函数都带参数:

def out(arg):
    def inner1(func):
        def inner2(num):
            print("before %s called [%s]." % (func.__name__, arg))
            print(func(num))
            print("after %s called [%s]." % (func.__name__, arg))
        return inner2
    return inner1 

@out("mymodule")
def myfunc1(num):
    print("myfunc1(%d) called."%num)
    return 'the args is :%d'%num
myfunc1(2)

结果:

绕晕了?没看明白吧?来个简单点的:

3).装饰器还可以带多个参数或者默认参数,用*args,**kwargs表示即可,这个什么类型的参数在前面讲过的,这里直接略过。传入多个参数方法和传入一个参数是一样的,不再解析

其实你应该发现了,装饰器带参数其实就是在两层的基础上又加了一层来为装饰器传参的。

8.装饰器传入函数作为参数

这个想想就觉得厉害了对不?

def auth(request,*kargs):
    print('认证成功')

def error_debug(request,*kargs):
    print('日志记录成功')

def out(auth_func,debug_func):
    def inner1(func):
        def inner2(request,*kargs):
            auth_func=auth(request,*kargs)

            #主体只是print的函数没有返回值,为空。不信的话你可以定义一个并打印看看就明白
            #当有异常抛出时不为空,所以这里设置不为空提前结束程序并返回异常
            if auth_func!=None:
                return auth_func

            main_func=func(request,*kargs)
            if main_func!=None:
                return main_func
            error_func=error_debug(request,*kargs)
            if error_func!=None:
                return error_func
        return inner2
    return inner1

@out(auth,error_debug)
def func(name,*age):
    print('%s正在开发项目'%name)

func('yang')

结果:

好的装饰器就到这,具体的开发运用的话,装饰器可以用到很多,比如可以传入一个类对象,传入另一个装饰器,还有在做项目时,写好一个框架,把框架作为装饰器等等的。具体的自己研究吧,反正装饰器挺强大的。

简单练习:(据说这是一道面试题)

请利用装饰器的方法将下面函数返回的结果小写:

def upper_func(string):

  return string.uppper()

upper_func(I Play Basketball')

洗礼灵魂,修炼python(30)--装饰器(2)—>装饰器总结+进阶使用的更多相关文章

  1. 洗礼灵魂,修炼python(29)--装饰器(1)—>利用经典案例解析装饰器概念

    前提必备 不急着进入正题,在前面函数作用域那一章介绍了闭包,全局变量局部变量,这里再看几个简单的闭包案例: 1):不带参数 注意: 1.这里的name属性是每个函数都有的,可以反馈函数名 2.temp ...

  2. 洗礼灵魂,修炼python(85)-- 知识拾遗篇 —— 深度剖析让人幽怨的编码

    编码 这篇博文的主题是,编码问题,老生常谈的问题了对吧?从我这一套的文章来看,前面已经提到好多次编码问题了,的确这个确实很重要,这可是难道了很多能人异士的,当你以为你学懂了,在研究爬虫时你发现你错了, ...

  3. 洗礼灵魂,修炼python(69)--爬虫篇—番外篇之feedparser模块

    feedparser模块 1.简介 feedparser是一个Python的Feed解析库,可以处理RSS ,CDF,Atom .使用它我们可从任何 RSS 或 Atom 订阅源得到标题.链接和文章的 ...

  4. 洗礼灵魂,修炼python(65)--爬虫篇—BeautifulSoup:“忘掉正则表达式吧,我拉车养你”

    前面解析了正则表达式,其实内容还挺多的对吧?确实挺适用的,不仅是python,其他语言或者web前端后端基本都要掌握正则表达式知识,但是你说,这么多,要完全的掌握,灵活运用的话,得搞多久啊?并且如果一 ...

  5. 11.python描述符---类的装饰器---@property

    描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...

  6. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  7. Python基础(八)装饰器

    今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f ...

  8. python高级 之(二) --- 类装饰器

    装饰器-初级 在不改变原有函数逻辑功能的基础上,为函数添加新的逻辑功能.使代码可读性更高.结构更加清晰.冗余度更低 简介 """ 闭包: 函数嵌套的格式就是闭包.写装饰器 ...

  9. Python 学习笔记9(装饰器,decorator)

    31 装饰器 装饰器可以对一个函数.方法或者类进行加工,是一种高级的python语法. 装饰函数 接收一个可调用对象作为输入参数,并返回一个新的可调用对象. 把函数传递给装饰器,然后增加新的功能,返回 ...

随机推荐

  1. Oracle PL/SQL,游标,过程

    1.PL/SQL  语法相关 -- SQL 语言只是访问,操作数据库的语言,而比并不是程序设计语言,因此不能用于程序开发. -- PL/SQL 是在标准SQl语言上进行过程性扩展后形成的程序设计语言, ...

  2. DeepLab 使用 Cityscapes 数据集训练模型

    原文地址:DeepLab 使用 Cityscapes 数据集训练模型 0x00 操作环境 OS: Ubuntu 16.04 LTS CPU: Intel® Core™ i7-4790K GPU: Ge ...

  3. 从零开始学 Web 之 Vue.js(三)Vue实例的生命周期

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. Java 8 新特性-菜鸟教程 (8) -Java 8 日期时间 API

    Java 8 日期时间 API Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理. 在旧版的 Java 中,日期时间 API 存在诸多问题,其中有: ...

  5. vscode使用汇总——常用插件、常用配置、常用快捷键

    一.代码提示快捷键设置:(keybindings.json) [ { "key": "ctrl+j", "command": "- ...

  6. Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate';

    springboot jdbc查询使用LocalDate报:Failed to convert value of type 'java.lang.String' to required type 'j ...

  7. SPI Flash(W25Q16DV) 驱动

    大体上可分为以下几个部分: 1.注册设备驱动 spi_register_driver 2.分配 mtd_info 结构体 3.配置 mtd_info 结构体 4.注册 mtd_info 结构体 构建 ...

  8. 【原】PHP从入门到精通2小时【图文并茂】

    原创内容,转载请注明. 主要内容: 搭建PHP开发环境 第一个helloworld程序 变量 全局变量 循环结构 函数 数组 面向对象编程 继承 接口 多态 日志 文件的读写 时间格式和时区 创建图形 ...

  9. Visual Studio日文乱码解决方法

    ---恢复内容开始--- 验证N多网上方法之后,没能解决,最后在控制面板->时钟.语言和区域->语言中左下角点击位置,进入区域窗口,管理选项中的更改系统区域语言,设为日语,解决,截图附上. ...

  10. VB.NET语法小结

    本人精通C#编程,VB没有开发经验,项目维护需要,特意整理了下VB语法,进行恶补.编程思想都是互通的,都是微软生的,语言大同小异. Imports System 一.(1)定义一个变量,并且初始化. ...