day 12 - 1 装饰器进阶
装饰器进阶
装饰器的简单回顾
装饰器
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数
装饰器的模式
def wrapper(func):
def inner(*args,**kwargs):
print("在被装饰的函数执行之前做的事")
ret =func(*args,**kwargs)
print("在被装饰的函数执行之前做的事")
return ret
return inner @wrapper #holiday = wrapper(holiday)
def holiday(day):
print("放假休息 %s 天"%day)
return '好开心' ret = holiday(3)
print(ret)
我们来看两个双下方法:__name__ 、__doc__
def wahaha():
'''
一个打印娃哈哈的函数
'''
print('娃哈哈') print(wahaha.__name__) #查看字符串格式的函数名
print(wahaha.__doc__) #document 显示函数的注释(限于多行注释)
#输出结果:
'''
wahaha 一个打印娃哈哈的函数 '''
接下来是 wraps 函数
from functools import wraps #引用 wraps 函数 def wrapper(func):
#wraps() 加在最内层函数正上方
#@wraps(func) #在不使用 wraps 函数时 返回结果: inner inner 函数的注释
@wraps(func) #使用 wraps 函数来装饰 inner 函数 返回结果:holiday 只是一个放假通知
def inner(*args,**kwargs):
'''
inner 函数的注释
'''
print("在被装饰的函数执行之前做的事")
ret =func(*args,**kwargs)
print("在被装饰的函数执行之前做的事")
return ret
return inner @wrapper #holiday = wrapper(holiday)
def holiday(day):
'''
只是一个放假通知
'''
print("放假休息 %s 天"%day)
return '好开心' print(holiday.__name__) #当不调用 wraps 函数时,显示的为 inner 函数的名称
print(holiday.__doc__) #当不调用 wraps 函数时,显示的为 inner 函数的注释 ret = holiday(3) #在使用装饰器 wraps 函数时,并不影响 holiday 函数的使用
print(ret) #这正是装饰器函数的特点
# 返回结果:
'''
在被装饰的函数执行之前做的事
放假休息 3 天
在被装饰的函数执行之前做的事
好开心
'''
假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
一个一个的取消掉? 没日没夜忙活3天。。。
过两天领导想通了,再让你加上。。。
#装饰器的三层嵌套 为的是给装饰器传入变量
import time
#flage = False #此处控制执行与否
flage = True
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flage:
start = time.time()
ret = func(*args,**kwargs)
end = time.time()
print(end - start)
return ret
else:
ret = func(*args,**kwargs)
return ret
return inner
return timmer @timmer_out(flage) #timmer_out(flage) 表示 timmer_out(flage) == timmer
def func(): #@ 表示 @timmer 即:func == timmer(func)
time.sleep(0.1)
print("结束") @timmer_out(flage)
def func2():
time.sleep(0.1)
print("结束") func()
func2()
多个装饰器,装饰一个函数
def wrapper(func):
def inner(*args,**kwargs):
print("-----1-----")
ret = func(*args,**kwargs)
print("*****1*****")
return ret
return inner def wrapper2(func):
def inner2(*args,**kwargs):
print("-----2-----")
ret = func(*args,**kwargs)
print("*****2*****")
return ret
return inner2 def wrapper3(func):
def inner3(*args,**kwargs):
print("-----3-----")
ret = func(*args,**kwargs)
print("*****3*****")
return ret
return inner3 @wrapper3
@wrapper2
@wrapper
def f():
print("in f")
return '就是这样'
print(f())
输出结果如下:
-----3-----
-----2-----
-----1-----
in f
*****1*****
*****2*****
*****3*****
就是这样
执行过成可参考下图

Python类中的装饰器在当前类中的声明与调用
class Test():
xx = False def __init__(self):
pass def test(func):
def wrapper(self, *args, **kwargs):
# print(self.xx)
return func(self, *args, **kwargs) return wrapper @test
def test_a(self, a, b):
print(f'ok,{a} {b}') # ok,12 13 t = Test()
t.test_a(12, 13)
注意:
1. 其中装饰器test是在类Test中声明并在其方法test_a中调用
2. 装饰器test内层wrapper函数的首参数是self
参考资料:
1. Python decorators in classes
day 12 - 1 装饰器进阶的更多相关文章
- day4之装饰器进阶、生成器迭代器
装饰器进阶 带参数的装饰器 # 某一种情况# 500个函数加装饰器, 加完后不想再加这个装饰器, 再过一个季度,又想加上去# 你可以设计你的装饰器,来确认是否执行 # 第一种情况 # 想要500个函数 ...
- Python函数--装饰器进阶
开放封闭原则 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对修改是封 ...
- Python装饰器进阶
装饰器进阶 现在,我们已经明白了装饰器的原理.接下来,我们还有很多事情需要搞清楚.比如:装饰带参数的函数.多个装饰器同时装饰一个函数.带参数的装饰器和类装饰器. 装饰带参数函数 def foo(fun ...
- (转)python装饰器进阶一
Python装饰器进阶之一 先看例子 网上有很多装饰器的文章,上来说半天也没让人看明白装饰器到底是个什么,究竟有什么用,我们直接来看几个例子. Python递归求斐波那契数列 def fibonacc ...
- python 基础篇 12 装饰器进阶
本节主要内容:1. 通⽤装饰器回顾2. 函数的有⽤信息3. 带参数的装饰器4. 多个装饰器同时装饰⼀个函数 ⼀. 通⽤装饰器的回顾开闭原则: 对增加功能开放. 对修改代码封闭装饰器的作⽤: 在不改变原 ...
- Python学习之装饰器进阶
函数知识回顾: 函数的参数分为:实参和形参. 实参:调用函数的时候传入的参数: 形参:分为3种(位置参数.默认参数.动态传参) 位置参数:必须传值 def aaa(a,b): print(a,b) a ...
- 从入门到自闭之python三大器--装饰器进阶
装饰器的进阶 有参装饰器: # def warpper(func): # def inner(*args,**kwargs): # user = input("user:") # ...
- CSIC_716_20191113【装饰器进阶以及迭代器】
装饰器的进阶主要包含叠加装饰器和有参装饰器 叠加装饰器:在一个被装饰的对象中,添加多个装饰器. 为什么要用叠加装饰器的原因: -每一个新的功能都应该写一个新的装饰器,否则会导致,代码冗余,结构不 ...
- Java设计模式12:装饰器模式
装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
随机推荐
- sprintf() 处理 float类型的数字,保留小数位等。
关于 sprintf()的百科地址: http://baike.baidu.com/view/1295144.htm sprintf(szText, "%[填空字元][宽度][.精度]f&q ...
- 测试利器 Postman
一.安装 官网:https://www.getpostman.com/ Postman是一个Chrome的一个插件工具,我们可以通过Chrome的应用商店进行进行搜索并安装,安装完成会在桌面上显示一个 ...
- TensorFlow升级1.4:Cannot remove entries from nonexistent file \lib\site-pack
https://blog.csdn.net/wishchin/article/details/78559313 https://blog.csdn.net/fool_frog/article/deta ...
- DAY1初识Python----变量及命名规则,注释,数据类型,常量,交互
1.认识和了解python python是一门解释型语言,弱类型语言 2.python发展史 2008年 2.X,3.X 3.第一个python程序 python语句可以写在命令行中,进行编 ...
- c#中内置委托
一.Action泛型委托 和之前委托最大区别在于不用定义委托,直接实例化委托(申明就可以),泛型其实就是选择数据类型,进行使得程序更加安全,并且也实现了委托的重载,最多选择16个参数. namespa ...
- tar压缩解压文件
查看visualization1.5.tar.gz 压缩包里面的内容: $ tar -tf visualization1.5.tar.gz 解压指定文件JavascriptVisualRelease/ ...
- ttribute "xmlns" was already specified for element "web-app".
今天导入了,一个javaweb项目,当自己对项目进行重命名的时候时候,但是web.xml直接爆出来一个"ttribute "xmlns" was already spec ...
- 【MSSQL】SQL Server的日期和时间类型
参考:SQL Server的日期和时间类型 SQL Server使用 Date 表示日期,time表示时间,使用datetime和datetime2表示日期和时间. 1.秒的精度 秒的精度是指TSQL ...
- 【.net】The source was not found, but some or all event logs could not be searched
1.案发现场: 注册服务的时候 2.解决方案: 用管理员身份运行CMD,再注册服务: I had to run Command Prompt with Administrator Rights.
- cmd快速设置本机ip和dns【转】
. 参考: https://wenku.baidu.com/view/74c59947336c1eb91a375dbe.html 家里配置如下 尾部的1不要忘了 netsh interface ip ...