Python进阶-IV-Wrapper高阶
一、装饰器回顾:
1、标准的装饰器示例
def trapper(func):
def inner(*args, **kwargs):
print('插入到被装饰函数前的功能!')
res = func(*args, **kwargs)
print('插入到被装饰函数后的功能!')
return res return inner @trapper
def func():
print('this is func!') func()
2、代码运行时间装饰器的优化
考虑如果同时有500个函数要解除检查代码运行时间,会不会费太多时间取注释掉语法糖?
是不是可以用标志控制,只改它就可以关闭或者打开装饰器
import time
ON_OFF = True # 装饰器控制开关,默认是关的 def count_time(func):
def inner(*args, **kwargs):
global ON_OFF # 如果不能使用该关键字,毕竟不安全
if ON_OFF:
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print('the function run use: %s'%(end - start))
return res
re = func(*args, **kwargs)
return re return inner @count_time
def func_wrapped():
time.sleep(0.233)
print('wrapping me!') @count_time
def woqu():
time.sleep(0.31415926)
print('wo ququququuuuuuuuu') func_wrapped()
woqu()
3、高阶优化代码运行时间装饰器
如果不使用global关键字,在局部域中使用全局变量,毕竟不安全,如何改造?
ef timmer_out(flag): # 在装饰器外再加一层函数,传入标志位,函数的最多嵌套三层!
def timmer(func):
def inner(*args, **kwargs):
if ON_OFF:
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print('the function run use: %s' % (end - start))
return res
re = func(*args, **kwargs)
return re return inner
return timmer @timmer_out(ON_OFF) # --> 等同于先执行timmer_out(ON_OFF)函数,返回:timmer;接着执行@timmer语法糖
def func_use_time():
time.sleep(0.233)
print('use ti me!') @timmer_out(ON_OFF)
def func_waste_time():
time.sleep(0.31415926)
print('wo waste') func_use_time()
func_waste_time()
二、@wraps的使用
解决在被装饰函数得不到原本函数名的问题
print(func.__name__) # 打印的结果时:inner ,因为被装饰后,func = trapper(func) 即 func = inner
# 如何得到它原本的名字了?
# 引入库
from functools import wraps def a_new_trapper(a_func):
@wraps(a_func)
def wrap_the_function():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()") return wrap_the_function @a_new_trapper
def a_function_requiring_trapper():
"""Hey yo! Decorate me!"""
print("I am the function which needs some trap to "
"remove my foul smell") print('a_function_requiring_trapper.__name__')
print(a_function_requiring_trapper.__name__)
三、多层装饰器
即多个装饰器同时装饰一个函数;
引入场景:网上购物时登录后,其他操作如:添加商品到购物车,删除购物车中的商品就不用再登录了!
同时登录用户的每个动作都要记录到日志中。
FLAG = False def login(func):
@wraps(func) # 此处也要加,否者写入日志的还是inner
def inner(*args, **kwargs):
global FLAG
while 1:
if FLAG is False:
name = input('请输入您的登录名:')
passwd = input('请输入您的登录密码:')
if name == 'lisi' and passwd == '':
FLAG = True
break
print('您输入的密码或者登录名不正确!请重新输入!')
continue
break
res = func(*args, **kwargs)
return res return inner def log(func):
@wraps(func)
def inner(*args, **kwargs):
res = func(*args, **kwargs)
with open('log', mode='a', encoding='utf-8') as f:
f.write(func.__name__ + '\n')
return res return inner @log
@login
def add_merc_to_cart():
print('I just add some merchandise to the cart!') @log
@login
def del_merc_in_cart():
print('I just del some merchandise in the cart!') add_merc_to_cart()
del_merc_in_cart()
多层装饰器的标准演示流程
ef wrapper1(func):
def inner(*args, **kwargs):
print('第一个装饰器wrapper1,在函数前的添加!')
res = func(*args, **kwargs)
print('第一个装饰器wrapper1,在函数后的添加!')
return res return inner def wrapper2(func):
def inner2(*args, **kwargs):
print('第二个装饰器wrapper2,在函数前的添加!')
res = func(*args, **kwargs)
print('第二个装饰器wrapper3,在函数后的添加!')
return res return inner2 def wrapper3(func):
def inner3(*args, **kwargs):
print('第三个装饰器wrapper3,在函数前的添加!')
res = func(*args, **kwargs)
print('第三个装饰器wrapper3,在函数后的添加!')
return res return inner3 @wrapper3
@wrapper2
@wrapper1
def wuha():
print('wu haaaaaaaaaaaaaaaaa!') wuha()
Python进阶-IV-Wrapper高阶的更多相关文章
- python进阶学习之高阶函数
高阶函数就是把函数当做参数传递的一种函数, 例如: 执行结果: 1.map()函数 map()接收一个函数 f 和一个list, 并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 l ...
- 《前端之路》之 JavaScript 进阶技巧之高阶函数(下)
目录 第二章 - 03: 前端 进阶技巧之高阶函数 一.防篡改对象 1-1:Configurable 和 Writable 1-2:Enumerable 1-3:get .set 2-1:不可扩展对象 ...
- 【python】python函数式编程、高阶函数
1.map() : python内置的高阶函数,接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并 返回. def f(x): r ...
- python 函数式编程:高阶函数,map/reduce
python 函数式编程:高阶函数,map/reduce #函数式编程 #函数式编程一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数 #(一)高阶函数 f=abs f print ...
- python入门16 递归函数 高阶函数
递归函数:函数内部调用自身.(要注意跳出条件,否则会死循环) 高阶函数:函数的参数包含函数 递归函数 #coding:utf-8 #/usr/bin/python """ ...
- python内置常用高阶函数(列出了5个常用的)
原文使用的是python2,现修改为python3,全部都实际输出过,可以运行. 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://bl ...
- Python之路 day3 高阶函数
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 变量可以指向函数,函数的参数能接收变量, 那么 ...
- Python 编程基础之高阶函数篇(一)
高阶函数:能接受函数作为参数的函数. 如: f=abs def add(x,y,f): return f(x)+f(y) 如果我们用:add(-5,9,f)来调用该高阶函数,则返回结果为:14 ...
- python笔记十三(高阶函数、装饰器)
一.高阶函数 函数只要有以下两个特征中一个就可以称为高阶函数: a:函数名作为一个实参传入另一个函数中 b:函数的返回值中包含函数名 下面我们用代码来感受一下这两种形式: import time # ...
- python高级特性和高阶函数
python高级特性 1.集合的推导式 列表推导式,使用一句表达式构造一个新列表,可包含过滤.转换等操作. 语法:[exp for item in collection if codition] if ...
随机推荐
- 团队作业第五次—项目冲刺-Day7
Day7 part1-SCRUM: 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 hunter--冲刺集合 团队名称 hunte ...
- chrome浏览器如何查看、修改、删除Cookie
1.chrome浏览器的cookie保存位置 C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data\Default 快捷键win+r--> ...
- JVM系列之三:类装载器子系统
0. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 1. 类的加载 虚拟机类装载器子系统:虚拟机把描述类的数据从class文件加载 ...
- Canal订阅binlog变更并结合kafka实现消息缓冲
阿里Canal项目请先了解:canal 考虑可能binlog大批量变更,如果直接通过Canal订阅binlog变动,会造成CanalClient会瞬间爆掉.为了解决这个问题,我们可以引入kafka做一 ...
- 带lambda参数的宏定义
我们知道有些宏的参数是表达式,在DEBUG启用的使用,可以输出一些日志,在RELEASE的时候,可以节省性能. 如下的宏定义是基于lambda表达式,可以处理一些复杂的逻辑. #ifdef debug ...
- .NET Core:路由
(1)模板路由 在Startup的Configure方法中配置: app.UseMvc(routes =>{ routes.MapRoute( name: "areas", ...
- LayUI-Table-添加禁止选中
LayUI这几年比较流行,里面的Table组件也比较强大,但是前面的CheckBox没有禁止选中功能,今天就来试试,看看能不能给添加一个禁止选中功能. Fork LayUI源码 LayUI项目地址 C ...
- rem与em的使用和区别
区别是:浏览器根据谁来转化成px值. 当使用rem单位,转换为像素大小取决于根元素的字体大小,即HTML元素的字体大小. 有一个比较普遍的误解,认为em单位是相对于父元素的字体大小.事实上,根据W3C ...
- 【转】用VMware 8安装Ubuntu 12.04详细过程(图解)
图解演示环境版本: 本机系统: WIN7 虚拟机:VMware Workstation 8 (英文版) 安装目标:Ubuntu Desktop 12.04 LTS (请点击这里)先下载好iso镜像文 ...
- 小程序开发笔记【五】---基于LBS附近动态查询
实现思路 : 获取用户当前位置经纬度坐标 查询动态时将经纬度坐标传给后台 后端通过sql语句计算经纬度坐标之间的距离 // 附近20公里发的动态 按时间排序 let sql = `SELECT * , ...