内容简介:一、装饰器首先,我们要了解到什么是开放封闭式原则?软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则。也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能。
一、装饰器
首先,我们要了解到什么是开放封闭式原则?
软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则。也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能。
总结:原则如下:
1、不修改源代码
2、不修改调用方式
目的:在遵循1和2原则的基础上扩展新功能。
二、什么是装饰器?
器:指的是工具,
装饰:指的是为被装饰对象添加新功能。
完整的含义:装饰器即在不修改装饰对象源代码与调用方式的前提下,为被装饰器对象添加新功能的一种函数,这个函数的特殊之处就在于它的返回值也是一个函数。
一般而言,我们想要拓展原来函数的代码,直接的办法就是侵入代码里面修改,例如:
import time
def index():
start_time=time.time()
time.sleep(2)
print('hello word,Linux公社www.linuxidc.com')
stop_time=time.time()
print('run time is %s'%(stop_time-start_time))
index()
//输出:
hello word,Linux公社www.linuxidc.com
run time is 2.000479221343994
以上代码就是让你过2秒才打印‘hello word’,下面我们要再添加一个新功能,和上面的功能一样,但是要传参数进去,过6秒输出结果。
修改1:
import time
def index():
time.sleep(2)
print('hello word,Linux公社www.linuxidc.com')
def home(name):
time.sleep(6)
print('welcome %s to home page'%name)
def wrapper(func):
start_time=time.time()
func('linuxidc')
stop_time=time.time()
print('run time is %s'%(stop_time-start_time))
wrapper(home)
//输出:
welcome linuxidc to home page
run time is 6.001421689987183
这样写感觉还是不怎么好,而且我们还修改了函数的调用方式,很不符合规矩。所以我们还是换一种方式来修改它。通过装饰器的方式。
修改2
import time
def index():
time.sleep(2)
print('hello word,Linux公社www.linuxidc.com')
def home(name):
time.sleep(6)
print('welcome to %s'%name)
def outter(func): # func为最原始的index 和home
def warpper():
start_time=time.time()
func('linuxmi')
stop_time=time.time()
print(stop_time-start_time)
return warpper
home=outter(home) ###home这个变量名是新赋值的,把原来的home给覆盖了。
home()
//输出:
welcome to linuxmi
6.00623631477356
这种方式虽然满足了不修改源代码和不修改调用方式的条件,但还是不能够实现两个函数同时运行的功能,说到底还是不行,我们还得想个方式出来。就是让他们两个同时运行。这时,我又想到了上节课所学的知识,就是*args和**kargs,用两个函数通过可变参数形式来实现内嵌函数的形式传入,所以它支持运行是构建参数列表,这对于以上两次不能解决的办法是最有效的。下面我们来试试,看到底能不能成功。
方式3:
import time
def index():
time.sleep(2)
print('hello word,Linux公社www.linuxidc.com')
def home(name):
time.sleep(6)
print('welcome %s to home page'%name)
def timmer(func): #func为最原始的home
def warpper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs) #调用了最原始的home
stop_time=time.time()
print(stop_time-start_time)
return res
return warpper
index=timmer(index) #为最新的index = wrapper
home=timmer(home) #为最新的home = wrapper
home(name='linuxmi') #wrapper=('linuxmi')
index() #wrapper
//输出:
welcome linuxmi to home page
6.003877401351929
hello word,Linux公社 www.linuxidc.com
2.0023157596588135
看吧,很快就实现了两个功能并用,而且我们还没有修改原始代码,还有调用方式。
其实很简单,我只是用了一个无参装饰器的模板,这个模板可以说是万能的,在以后很多的函数代码都可以用这种方式来套用。
模板:
def outer(func):
def inner(*args,**kwargs):
res=func(*args,**kwargs)
return res
return inner
现在又有问题来了,我们调装饰器的时候,每调一次,又要把装饰器对象传进来,调一次又传一次,这样不会觉得很麻烦吗?那么我们又想到了一种方法,就是 装饰器语法糖,在被装饰对象的上面加@timmer 用它来取代 index=timmer(index)
并且把返回值正常的返回给它。
import time
def timmer(func): #func为最原始的home
def warpper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs) #调用了最原始的home
stop_time=time.time()
print(stop_time-start_time)
return res
return warpper
@timmer #就是取代底下的 index=timmer(index)
def index():
time.sleep(2)
print('hello word,Linux公社www.linuxidc.com')
@timmer #就是取代底下的home=timmer(home) home(name='yuan')
def home(name):
time.sleep(6)
print('welcome %s to home page'%name)
index()
home('linuxidc.com')
//输出:
hello word,Linux公社 www.linuxidc.com
2.001802682876587
welcome linuxidc.com to home page
6.005476951599121
注意:这里的timmer函数就是最原始的装饰器,它的参数就是一个函数,然后返回值也是一个函数。其中作为参数的这个函数index()和hemo(name)就是在返回函数的wrapper()的内部执行。然后再这两个函数的前面加上@timmer,index()和home(name)函数就相当于被注入了计时功能,现在只需要调用index()和home(‘yuan’),它就已经变身为‘新功能更多的函数了。’
所以这里的装饰器就像一个注入的符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数。
用装饰器来实现认证功能:
import time
current_user={
'username':None,
#'login_time':None
}
def auth(func):
# func = index
def wrapper(*args,**kwargs):
if current_user['username']:
print('已经登录过了')
res=func(*args,**kwargs)
return res
uname = input('输入用户名:').strip()
pwd = input('密码:').strip()
if uname == 'linuxmi' and pwd == '123':
print('登录成功')
current_user['username']=uname
res = func(*args,**kwargs)
return res
else:
print('用户名或密码错误')
return wrapper
@auth #index = auth(index)
def index():
time.sleep(1)
print('welcom to index page')
@auth
def home(name):
time.sleep(2)
print('welcome %s to home page'%name)
input()
home('linuxmi')
有参数的装饰器来用于用户认证
import time
current_user={
'username':None,
# 'login_time':None
}
def auth(func):
# func=index
def wrapper(*args,**kwargs):
if current_user['username']:
print('已经登陆过了')
res=func(*args,**kwargs)
return res
uname=input('用户名>>: ').strip()
pwd=input('密码>>: ').strip()
if uname == 'linuxmi' and pwd == '123':
print('登陆成功')
current_user['username']=uname
res=func(*args,**kwargs)
return res
else:
print('用户名或密码错误')
return wrapper
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(stop_time-start_time)
return res
return wrapper
@timmer # timmer 统计的是auth+index的执行时间
@auth
def index():
time.sleep(1)
print('welcome to index page')
return 122
index()
叠加多个装饰器:
import time
current_user={
'username':None,
# 'login_time':None
}
def auth(func):
# func=index
def wrapper(*args,**kwargs):
if current_user['username']:
print('已经登陆过了')
res=func(*args,**kwargs)
return res
uname=input('用户名>>: ').strip()
pwd=input('密码>>: ').strip()
if uname == 'linux' and pwd == '123':
print('登陆成功')
current_user['username']=uname
res=func(*args,**kwargs)
return res
else:
print('用户名或密码错误')
return wrapper
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(stop_time-start_time)
return res
return wrapper
@timmer # timmer 统计的是auth+index的执行时间
@auth
def index():
time.sleep(1)
print('welcome to index page')
return 122
index()
更多 Python 相关信息见 Python 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=17
Linux公社的RSS地址 : https://www.linuxidc.com/rssFeed.aspx
本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-02/157150.htm
以上所述就是小编给大家介绍的《Python函数装饰器的使用示例分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Go 函数特性和网络爬虫示例
- Flex弹出窗口请求Action函数示例
- JS实现运动缓冲效果的封装函数示例
- oracle中decode函数的使用方法示例
- Hive 中使用 UDF (用户自定义函数) 示例
- Python实现对一个函数应用多个装饰器的方法示例
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Persuasive Technology
B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95
Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!