装饰器进阶
装饰器的简单回顾
装饰器
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数
装饰器的模式
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)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
随机推荐
-
Webform(六)——登录状态保持(Cookies内置对象)
用户用浏览器访问一个网站,由于采用的http的特性,Web服务器并不能知道是哪一个用户正在访问,但一些网站,希望能够知道访问者的一些信息,例如是不是第一次访问,访问者上次访问时是否有未做完的工作,这次 ...
-
python用Tesseract读取图片中的中文,出现乱码
到http://download.csdn.net/detail/wanghui2008123/7621567下载中文简体包 然后找到tessdata目录,把eng.traineddata替换为chi ...
-
Pro Git 读书笔记
一. 起步 1. 集中式版本控制缺点:*服务器的单点故障. 分布式版本控制优点:客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来. 这么一来,任何一处协同工作用的服务器发生故障,事后 ...
-
ant非法字符:\65279 错误
ant非法字符:\65279 错误前段时间用ant把项目打包,遇到一个问题:编译java文件的时候,有些java文件报非法字符 \65279错误,在网上找和很多方法,也试了很多方法,换JDK,网上说的 ...
-
php入门自学小展示
<!doctype html> <html> <head> <title>PHP函数小展示</title> </head> &l ...
-
metaq spring
spring metaq spring bean 配置 <bean id="sessionFactory" class="com.taobao.metamorpho ...
-
02-CSS&;JS
今日目标 使用CSS完成网站首页的优化 使用CSS完成网站注册页面的优化 使用JS完成简单的数据校验 使用JS完成图片轮播效果 教学目标: - 了解CSS的概念 - 了解CSS的引入方式 - 了解CS ...
-
【emWin】例程二十四:窗口对象——Header
简介: HEADER 小工具用于标记表格的列,本例程示例演示如何使用HEADER小工具. 触摸校准(上电可选择是否进入校准界面) 实验指导书及代码包下载: 链接:http://pan.baidu.co ...
-
C# 控件
.ascx:Web窗体用户控件.用来存放独立的用户控件,可提供众多页面使用: <%@ Control Language="C#" AutoEventWireup=" ...
-
DNSLOG在渗透测试中的玩法儿
首先了解一下DNS是啥??? DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读 ...