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

装饰器

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. VueRouter 源码深度解析

    VueRouter 源码深度解析 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还 ...

  2. shell编程中的循环语句

    while循环直接从文件中读取 while read line do command done < filename until循环 until 条件 do command done for循环 ...

  3. Hive的union和join操作

    建表语句: create table  tb_in_base (    id  bigint,    devid bigint,     devname string  ) partitioned b ...

  4. list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构

    list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...

  5. Crypto++应用:非对称加密RSA

    1,非对称加密RSA: (1)乙方生成两把密钥(公钥和私钥).公钥是公开的,任何人都可以获得,私钥则是保密的. (2)甲方获取乙方的公钥,然后用它对信息加密. (3)乙方得到加密后的信息,用私钥解密. ...

  6. 用Redis作Mysql数据库缓存

    使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按 ...

  7. shiro教程2(自定义Realm)

    通过shiro教程1我们发现仅仅将数据源信息定义在ini文件中与我们实际开发环境有很大不兼容,所以我们希望能够自定义Realm. 自定义Realm的实现 创建自定义Realmjava类 创建一个jav ...

  8. git入门(廖雪峰老师)

    根据廖雪峰老师的git教程进行学习总结: 1.之前上班用的都是svn进行管理,那么svn和git有什么区别呢? svn是集中式的版本控制系统,而git是分布式版本控制系统,那么集中式和分布式版本控制系 ...

  9. 具体CAS操作实现(无锁算法)

    具体CAS操作 上一篇讲述了CAS机制,这篇讲解CAS具体操作. 什么是悲观锁.乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优 ...

  10. 最优-scroll事件的监听实现

    1. 背景和目标 前端在监听scroll这类高频率触发事件时,常常需要一个监听函数来实现监听和回调处理.传统写法上利用setInterval或setTimeout来实现. 为了减小 CPU 开支,往往 ...