day17 装饰器(上)
一、什么是装饰器
装饰:是对其他已有的事物添加额外具有一定意义的事物
器:是一种工具,在程序内可以定义成函数
合到一起就是:
装饰器就是一个函数,为了给其他函数添加额外的功能
二、为什么要有装饰器
这里要引入一个设计程序的一个概念:开放封闭原则
开放:指的是对扩展功能是开放的,就是指原来设计的功能是可装饰的
封闭:指的是对修改源代码是封闭的,原来代码的某一个功能可能在不同场景有多种不同的应用,一旦修改会造成连锁反应。为此,一般情况下上线的功能不做源代码的修改
装饰器就是在不修改被装饰对象的
三、无参装饰器的使用
需求:不修改index函数的源代码,以及调用方式的前提下加统计函数运行时间的功能
def index(x,y):
print(x,y)
return 123
res = index(1,2)
print(res)
>>>1,2
>>>123
第一步:我们先要回忆函数的开放封闭原则,不能对函数源代码修改,我们只能在函数外修改
import time
start = time.time()
def index(x,y):
print(x,y)
return 123
stop = time.time()
print(stop - start)
res = index(1,2)
print(res)
>>>0.0007340908050537
>>>1,2
>>>123
第二步:这里我们已经实现了不修改index源码也不修改参数调用方式的情况下添加新功能了但是这样写的局限性很高,我们只对当前位置的函数index进行了装饰,当然在整个程序里index不可能只调用一次,如果对每个地方都修改就很麻烦。所以我们应该想到,把装饰器写成函数
import time
def index(x, y):
print(x, y)
return 123
def outter(*args,**kwargs):
start = time.time()
res = index(*args,*kwargs)
stop = time.time()
print(stop - start)
return res
res = outter(1,2)
print(res)
>>>1,2
>>>0.0007340908050537
>>>123
第三步:这里我们看起来是节省了重复代码,可以直接用outter来当更新过的index,但是我们会发现我们这个outter被写死了,我们这个装饰器只能为index函数工作,这是不符合常理的,所以我们应该把它关于index的值作为变量重新传,但是我们outter的参数已经不能修改了必须是*,**,所以这里就用到了闭包函数的应用
import time
def index(x,y):
print(f"index{x},{y}")
return 123
def name(your_name):
print(f"your name:{your_name}")
return 456
def timmer(func):
def outter(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
stop = time.time()
print(stop - start)
return res
return outter
index = timmer(index)
res = index(1,2)
print(res)
>>>1,2
>>>0.0007340908050537
>>>123
name = timmer(name)
res = name("hz")
print(res)
>>>your name:hz
>>>0.0008175373077393
>>>456
最后一步:为了程序员编写程序的方便,引入了语法糖的概念,语法糖就是,在编译结果不便的情况下,让代码更加简洁优美。此处语法糖的应用项待遇代替了装饰器调用的代码
import time
def timmer(func):
def outter(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
stop = time.time()
print(stop - start)
return res
return outter
#如果此处有多个装饰器,按照从下到上的顺序装饰
@timmer
#@timmer相当于 index=timmer(index)
def index(x,y):
print(f"index{x},{y}")
return 123
@timmer
#@timmer相当于 name=timmer(name)
def name(your_name):
print(f"your name:{your_name}")
time.sleep(1)
return 456
res = index(1,2)
print(res)
>>>1,2
>>>0.0007340908050537
>>>123
res = name("hz")
print(res)
>>>your name:hz
>>>0.0008175373077393
>>>456
day17 装饰器(上)的更多相关文章
- python高级之装饰器
python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...
- python迭代器,生成器,装饰器,context模块
迭代器iteration 是访问集合元素的一种方式,只能往前不能往后迭代器的特点:1,访问者不需要关注迭代器内部结构,只需通过next()不断取下一个内容2,访问不能回退3,循环较大数据集合时,省内存 ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- Python入门笔记(19):Python函数(2):函数/方法装饰器
一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下: @decorator(dec_opt_ar ...
- 第二篇:python高级之装饰器
python高级之装饰器 python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- 从C#到TypeScript - 装饰器
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- Python装饰器的解包装(unwrap)
在Python 3.4 中,新增一个方法unwrap,用于将被装饰的函数,逐层进行解包装. inspect.unwrap(func, *, stop=None) unwrap方法接受两个参数:func ...
- Python全栈开发之---装饰器
1.装饰器的形成过程 import time def func1(): print('in func1') def timer(func): def inner(): start = time.tim ...
随机推荐
- 【快手初面】要求3个线程按顺序循环执行,如循环打印A,B,C
[背景]这个题目是当时远程面试时,手写的题目.自己比较惭愧,当时写的并不好,面试完就又好好的完善了下. 一.题意分析 3个线程要按顺序执行,就要通过线程通信去控制这3个线程的执行顺序. 而线程通信的方 ...
- 强类型sql生成助手类
不使用表达式树,使用强类型生成where子句,好处是性能高,相比表达式树生成的sql,10倍+ 目前只支持生成where条件.查询语句,后期会增加生成Update SQL where子句支持相等.比较 ...
- kibana的Dev Tool中如何对es进行增删改查
kinaba Dev Tool中对es(elasticSearch)进行增删改查 一.查询操作 查询语句基本语法 以下语句类似于mysql的: select * from xxx.yyy.topic ...
- local 对象补充
昨日回顾 1 @app.before_first_request,再项目启动后接收到的第一个请求,会执行before_first_request,他再@app.before_request之前执行.他 ...
- MyBatis运行流程及入门第一个程序
1. mybatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...
- Maven 在Mac下的配置
1.下载maven 解压到本地目录 官网下载Maven安装文件,如apache-maven-3.2.3-bin.tar.gz,然后解压到本地目录 解压: tar -zxcf apache-maven- ...
- JDBC——什么是JDBC?
JDBC:Java数据库连接(Java DataBase Connectivity),是Java语言中用来规范客户端如何程序如何来访问数据库的应用程序接口(API),提供了诸如查询和更新数据库中数据的 ...
- SQL注入之常用工具sqlmap
通常来说,验证一个页面是否存在注入漏洞比较简单,而要获取数据,扩大权限,则要输入很复杂的SQL语句,有时候我们还会对大量的URL进行测试,这时就需要用到工具来帮助我们进行注入了. 目前流行的注入工具有 ...
- ajax前后端交互原理(1)
1.Node.js简介 1.1.前后台数据交互流程 在web开发中,我们经常听说前端和后台,他们分别是做什么具体工作的呢?他们怎样交互的呢?我们得把这些基础的问题都搞明白了,才有一个大致的学习方向,首 ...
- JQuery 优缺点略谈
1.jQuery实现脚本与页面的分离 ; 2.最少的代码做最多的事情; 3.性能; 在大型JavaScript框架中,jQuery对性能的理解最好.尽管不同版本拥有众多新功能,其最精简版本只有18KB ...