洗礼灵魂,修炼python(30)--装饰器(2)—>装饰器总结+进阶使用
在上一篇博文的经典案例中,我想你应该对装饰器有很好的了解了,不过光有那些还不够真的,还需要总结和进阶一下,所以本篇博文解析装饰器进阶。
装饰器
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)—>装饰器总结+进阶使用的更多相关文章
- 洗礼灵魂,修炼python(29)--装饰器(1)—>利用经典案例解析装饰器概念
前提必备 不急着进入正题,在前面函数作用域那一章介绍了闭包,全局变量局部变量,这里再看几个简单的闭包案例: 1):不带参数 注意: 1.这里的name属性是每个函数都有的,可以反馈函数名 2.temp ...
- 洗礼灵魂,修炼python(85)-- 知识拾遗篇 —— 深度剖析让人幽怨的编码
编码 这篇博文的主题是,编码问题,老生常谈的问题了对吧?从我这一套的文章来看,前面已经提到好多次编码问题了,的确这个确实很重要,这可是难道了很多能人异士的,当你以为你学懂了,在研究爬虫时你发现你错了, ...
- 洗礼灵魂,修炼python(69)--爬虫篇—番外篇之feedparser模块
feedparser模块 1.简介 feedparser是一个Python的Feed解析库,可以处理RSS ,CDF,Atom .使用它我们可从任何 RSS 或 Atom 订阅源得到标题.链接和文章的 ...
- 洗礼灵魂,修炼python(65)--爬虫篇—BeautifulSoup:“忘掉正则表达式吧,我拉车养你”
前面解析了正则表达式,其实内容还挺多的对吧?确实挺适用的,不仅是python,其他语言或者web前端后端基本都要掌握正则表达式知识,但是你说,这么多,要完全的掌握,灵活运用的话,得搞多久啊?并且如果一 ...
- 11.python描述符---类的装饰器---@property
描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...
- python基础整理4——面向对象装饰器惰性器及高级模块
面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...
- Python基础(八)装饰器
今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f ...
- python高级 之(二) --- 类装饰器
装饰器-初级 在不改变原有函数逻辑功能的基础上,为函数添加新的逻辑功能.使代码可读性更高.结构更加清晰.冗余度更低 简介 """ 闭包: 函数嵌套的格式就是闭包.写装饰器 ...
- Python 学习笔记9(装饰器,decorator)
31 装饰器 装饰器可以对一个函数.方法或者类进行加工,是一种高级的python语法. 装饰函数 接收一个可调用对象作为输入参数,并返回一个新的可调用对象. 把函数传递给装饰器,然后增加新的功能,返回 ...
随机推荐
- linux pidstat 命令详解
pidstat 概述 pidstat是sysstat工具的一个命令,用于监控全部或指定进程的cpu.内存.线程.设备IO等系统资源的占用情况.pidstat首次运行时显示自系统启动开始的各项统计信息, ...
- Spring Boot - 修改Tomcat默认的8080端口
前言 默认情况下,Spring Boot内置的Tomcat服务会使用8080端口启动,我们可以使用以下任何技巧去更改默认的Tomcat端口: 注:我们可以通过server.port=0配置,去自动配置 ...
- solr入门
Solr采用Lucene搜索库为核心,提供全文索引和搜索开源企业平台,提供REST的HTTP/XML和JSON的API,如果你是Solr新手,那么就和我一起来入门吧!本教程以solr4.8作为测试环境 ...
- Solidity中uint转string
在<Solidity中uint转bytes>中,我们知道unit如何转换成bytes,其实把uint转换成string,就是在最后加上string(bytes变量)即可,如下所示: pra ...
- MONGODB(四)——DBObject与JavaBean转换
一.DBObject 转为 JavaBean /** * 将实体Bean对象转换成DBObject * */ public static <T> DBObject beanToDBObje ...
- [转]Angular4 引用 material dialog时自定义对话框/deep/.mat-dialog-container
本文转自:https://blog.csdn.net/qq_24078843/article/details/78560556 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...
- QT中全局变量的定义
多的就不说了,本来就是一个简单地内容,只是不会的话会很头疼 我们首先新建两个文件,文件名可以自定义,我们在这里定义为variate.h 和 variate.cpp 当然了,后缀是不能变的. 和函数一样 ...
- SQL 同一张表中相同字段的内容合并为一条记录(不同字段的那一列每个记录后面加逗号)
一.创建表 create table stuUnion ( sid int identity primary key, cid int, id ) ) 二.添加数据 insert into stuUn ...
- 【Java并发编程】14、Thread,线程说明
线程的状态:New.Runnable.Blocked.Waiting.Timed waiting.Terminated 1. RUNNABLE,对应"就绪"和"运行&qu ...
- SOA、SOAP、RFC、RPC、IETF
SOA: 全称:Servuce - oriented Architecture 说明:面向服务架构 就是说将软件按照功能设计成一个个服务,这些服务用标准的方式定义接口.并通过标准的协议进行调用. SO ...