裝飾器不能修改被裝飾的函數的源代碼和調式方法,從而起到裝飾這個函數的做用。python
好比,有一個函數,在不修改它的狀況下獲得它的運行時間。服務器
#-*- 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函數。從而獲得它的運行時間。app
上面只是簡單的裝飾,當被裝飾的函數有參數時該怎麼辦呢?函數
在裝飾器函數timer裏,就須要把參數傳進去了。spa
#-*- 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去裝飾某個函數時,若是裝飾器也有參數呢? 好比blog
@auth(auth_type='local')
@auth(auth_type='ldap')
使用不一樣的參數來使的調用的方式不一樣,這使用在裝飾器裏能夠經過加一層函數來解決。utf-8
#-*- 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('\033[32;1mUser has passed authentication\033[0m') return func(*args, **kwargs) else: print('\033[31;1mInvalid username or password\033[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裏的參數傳進去,第二個函數將被裝飾的函數當成參數傳入,第三個函數是把被裝飾的函數裏的參數傳入。input
裝飾器的常見三種使用就是這樣了。io