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)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
随机推荐
- gradle的安装配置成功标志
gradle主要位于AndroidStudio中 看我的目录 在环境变量里添加用户变量 GRADLE_HOME 然后在环境变量 path 中增加 %GRADLE_HOME%\bin;,如图所示 测试配 ...
- 第二十二篇-Guideline基准线
效果图: 前5个是button填充的,最后一个是线性布局下放置一个button在填充. layout.xml <?xml version="1.0" encoding=&qu ...
- JVM 辣鸡回收
垃圾回收算法 标记清除法 先标记出需要回收的对象,然后一次性回收.缺点:会产生内存碎片,并且效率也不高. 标记压缩法 先标记出需要回收的对象,然后让存活对象向一端移动,移动的过程中进行回收辣鸡.避免了 ...
- IDEA或Webstorm设置Ctrl+滚轮调整字体大小
按Ctrl+Shift+A,出现搜索框 输入mouse: 点击打开这个设置:勾选 点击ok,之后就可以通过Ctrl+滚轮 调整字体大小了.
- (最小生成树 Prim) nyoj1403-沟通无限校园网
题目描述: 校园网是为学校师生提供资源共享.信息交流和协同工作的计算机网络.校园网是一个宽带.具有交互功能和专业性很强的局域网络.如果一所学校包括多个学院及部门,也可以形成多个局域网络,并通过有线或无 ...
- (DFS)P1605 迷宫 洛谷
题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...
- mysql视图、触发事务、存储过程
视图 视图是一个虚拟表(非真实存在的),其本质就是根据SQL语言获取动态的数据集,并为其命名,用户使用时只需要使用名称即可获得结果集,可以将结果集当做表来使用. 视图是存在数据库中的,如果我们程序中使 ...
- 2017-12-15python全栈9期第二天第一节之昨日内容回顾
- break #立即终止本次循环
#!/user/bin/python# -*- coding:utf-8 -*-# print(111)# while True:# print(222)# print(333)# break #立即 ...
- my live boadband
id_boadband tel: 02511931324 ¥1600 包2年,10MB/S =100Mb,2018.12.1 ~ 2020.12.1 end