一、装饰器回顾:

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高阶的更多相关文章

  1. python进阶学习之高阶函数

    高阶函数就是把函数当做参数传递的一种函数, 例如: 执行结果: 1.map()函数 map()接收一个函数 f 和一个list, 并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 l ...

  2. 《前端之路》之 JavaScript 进阶技巧之高阶函数(下)

    目录 第二章 - 03: 前端 进阶技巧之高阶函数 一.防篡改对象 1-1:Configurable 和 Writable 1-2:Enumerable 1-3:get .set 2-1:不可扩展对象 ...

  3. 【python】python函数式编程、高阶函数

    1.map() : python内置的高阶函数,接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并            返回. def f(x): r ...

  4. python 函数式编程:高阶函数,map/reduce

    python 函数式编程:高阶函数,map/reduce #函数式编程 #函数式编程一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数 #(一)高阶函数 f=abs f print ...

  5. python入门16 递归函数 高阶函数

    递归函数:函数内部调用自身.(要注意跳出条件,否则会死循环) 高阶函数:函数的参数包含函数 递归函数 #coding:utf-8 #/usr/bin/python """ ...

  6. python内置常用高阶函数(列出了5个常用的)

    原文使用的是python2,现修改为python3,全部都实际输出过,可以运行. 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://bl ...

  7. Python之路 day3 高阶函数

    #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 变量可以指向函数,函数的参数能接收变量, 那么 ...

  8. Python 编程基础之高阶函数篇(一)

      高阶函数:能接受函数作为参数的函数. 如: f=abs def   add(x,y,f): return f(x)+f(y) 如果我们用:add(-5,9,f)来调用该高阶函数,则返回结果为:14 ...

  9. python笔记十三(高阶函数、装饰器)

    一.高阶函数 函数只要有以下两个特征中一个就可以称为高阶函数: a:函数名作为一个实参传入另一个函数中 b:函数的返回值中包含函数名 下面我们用代码来感受一下这两种形式: import time # ...

  10. python高级特性和高阶函数

    python高级特性 1.集合的推导式 列表推导式,使用一句表达式构造一个新列表,可包含过滤.转换等操作. 语法:[exp for item in collection if codition] if ...

随机推荐

  1. 安装Oracle 11g时遇到“【INS-13001】此环境不满足最低配置”的问题解决

    一.问题如下: win10一般容易出现这个问题,可能是版本兼容的关系.  二.解决方法: 在Oracle 11g解压出的文件夹下寻找cvu_prereq.xml文件: 路径:database\stag ...

  2. 慕课网springboot博客系统开发(一)----spring initializr的使用 gradle构建项目

    spring initializr工具的地址:https://start.spring.io/:通过它可以很方便的创建springboot项目 这里我们选择使用gradle作为项目的构建工具,此spr ...

  3. long 在不同操作系统下所占用的字节数

    不同平台下C\C++数值数据类型长度如下: 类型 win32 win64 linux32 linux64 其中long类型和指针类型需要特别注意,编写跨平台的软件时尽量不要使用long类型,或者需要对 ...

  4. SpringBoot第十九篇:邮件服务

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11118340.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   邮件的重要 ...

  5. SpringCloud与Dubbo区别对比

    1:SpringCloud与Dubbo区别对比 (1):活跃度 目前SpringCloud的活跃度明显远高于Dubbo(参考github) (2):主要区别   Dubbo Spring Cloud ...

  6. ROS向节点传递参数

    ROS的节点有很多中调用方式,包括rosrun,launch,直接运行等,向节点内传递参数的方式也有很多. 1. rosrun + 参数服务器传递 ros::init(argc, argv, &quo ...

  7. ant-design自定义FormItem--上传文件组件

    自定义上传组件,只需要在内部的值变化之后调用props中的onChange方法就可以托管在From组件中, 此外为了保证,初始化值发生变化后组件也发生变化,需要检测initialValue 变化,这是 ...

  8. 折腾linux随笔 之 关闭Budgie默认自动隐藏应用的菜单栏 与 Gnome系桌面应用菜单无内容解决

    关闭Budgie默认自动隐藏应用菜单栏 首选项 -> 设置 -> 通用辅助功能 -> 打开 始终显示通用辅助菜单 后的开关 -> 注销桌面重新登录. done. 解决Gnome ...

  9. wget下载阿里云oss的文件报错403

    问题 在实际工作中,我们为了方便,会将一些脚本储存在云端(阿里云OSS),这样方便我们使用和下载,但是在实际的使用过程中,我们会遇到一些问题. 示例链接:https://djxlsp.oss-cn-s ...

  10. 代码语法高亮踩坑-原理,问题, PRE元素及htmlentity

    语法高亮库基础原理 在研究使用能够在web页面上代码语法高显的解决方案时,发现有很多现成的开源库.比较中意的有prism.js,highlightjs.他们的原理基本上核心就两点: 1. 利用html ...