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 ...
随机推荐
- java循环控制语句loop使用
java中break和continue可以跳出指定循环,break和continue之后不加任何循环名则默认跳出其所在的循环,在其后加指定循环名,则可以跳出该指定循环(指定循环一般为循环嵌套的外循环) ...
- Code Review最佳实践(转)
我一直认为Code Review(代码审查)是软件开发中的最佳实践之一,可以有效提高整体代码质量,及时发现代码中可能存在的问题.包括像Google.微软这些公司,Code Review都是基本要求,代 ...
- ASP.NET Core中使用MialKit实现邮件发送
# 导包 首先我们需要导入 MailKit NuGet包,NuGet安装包命令在下方拓展介绍中. # 引用命名空间 using MailKit.Net.Smtp; using MimeKit; # 邮 ...
- Mysql外键约束之CASCADE、SET NULL、RESTRICT、NO ACTION
Mysql中有目前只有InnoDB引擎支持外键约束,InnoDB中外键约束定义的语法如下: ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN ...
- Qt实现表格树控件-支持多级表头
目录 一.概述 二.效果展示 三.实现方式 四.多级表头 1.数据源 2.表格 3.QStyledItemDelegate绘制代理 五.测试代码 六.相关文章 原文链接:Qt实现表格树控件-支持多级表 ...
- GIT篇章(一)
git的使用 创建代码版本 cd进入到自己希望存储代码的目录路径,并创建本地仓库.git[pycharm直接打开终端就是项目根目录了.无须cd了] 新创建的本地仓库.git是个空仓库 cd 目录路径 ...
- 获取post传输参数
1.获取post参数可以用 传输参数为 a=aa&b=bb这种 public static SortedDictionary<string, string> GetRequestP ...
- NLog日志
配置nlog 1.从nuget中获取配置 安装前2个文件 然后会有一个NLog.config 更改内容 <?xml version="1.0" encoding=" ...
- Generate a document using docxtemplater
生成word文档,更新word内容 http://javascript-ninja.fr/docxtemplater/v1/examples/demo.html https://docxtempl ...
- Android源码分析(十五)----GPS冷启动实现原理分析
一:原理分析 主要sendExtraCommand方法中传递两个参数, 根据如下源码可以知道第一个参数传递delete_aiding_data,第二个参数传递null即可. @Override pub ...