装饰器不能修改被装饰的函数的源代码和调式方法,从而起到装饰这个函数的作用。
比如,有一个函数,在不修改它的情况下得到它的运行时间。
#-*- coding:utf-8 -*-
'''
@auther: Starry
@file: decorator1.py
@time: 2018/1/18 23:11
'''
import time
def timer(func):
def deco():
start_time = time.time()
func()
end_time = time.time()
print('the func run time is %s'%(end_time - start_time))
return deco
@timer #test1 = timer(test1)
def test1():
time.sleep(3)
print('in the test1!')
test1()
使用装饰器 timer 来装饰test1函数。从而得到它的运行时间。
上面只是简单的装饰,当被装饰的函数有参数时该怎么办呢?
在装饰器函数timer里,就需要把参数传进去了。
#-*- coding:utf-8 -*-
'''
@auther: Starry
@file: decorator2.py
@time: 2018/1/18 23:31
'''
import time
def timer(func):
def deco(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print('the func run time is %s'%(end_time - start_time))
return deco
@timer
def test2(name):
print("name:"+name)
test2('Starry')
被装饰的函数有参数解决了,但又有一种情况了,当调用装饰器timer去装饰某个函数时,如果装饰器也有参数呢? 比如
@auth(auth_type='local')
@auth(auth_type='ldap')
使用不同的参数来使的调用的方式不同,这使用在装饰器里可以通过加一层函数来解决。
#-*- coding:utf-8 -*-
'''
@auther: Starry
@file: decorator3.py
@time: 2018/1/18 23:33
'''
username, password = 'starry','sky'
def auth(auth_type):
print('auth func:',auth_type)
def wrapper(func):
def deco(*args, **kwargs):
print('wrapper func:', *args, **kwargs)
if auth_type == 'local':
user = input('please input your username:')
passwd = input('please input your password:')
if user == username and password == passwd:
print(' 33[32;1mUser has passed authentication 33[0m')
return func(*args, **kwargs)
else:
print(' 33[31;1mInvalid username or password 33[0m')
elif auth_type == 'ldap':
print('服务器端验证')
return deco
return wrapper
def index():
print('welcome to index page')
@auth(auth_type='local')
def home():
print('welcome to home page')
return 'from home'
@auth(auth_type='ldap')
def bbs():
print('welcome to bbs page')
index()
print(home())
bbs()
函数里嵌套函数,嵌套了两次,第一个函数是把装饰器timer里的参数传进去,第二个函数将被装饰的函数当成参数传入,第三个函数是把被装饰的函数里的参数传入。
装饰器的常见三种使用就是这样了。