python装饰器
装饰器本质上也是一个函数,装饰器函数用来修饰其他函数,在不改变原函数代码的情况下为函数增加功能而无需修改调用方式
不带参函数的装饰
1 import time 2 def show_time(func):# 装饰器函数调用原功能函数并返回一个新的函数对象 3 def inner(): 4 start = time.time() 5 func() 6 end = time.time() 7 print('函数执行时间为;%s' % (end - start)) 8 return inner 9 10 @show_time# 这一步相当于func1 = show_time(func1) 11 def func1(): 12 print('func1') 13 time.sleep(1) 14 print('func1 again') 15 func1()# 在这里调用func1实际上是执行了show_time函数里的inner函数
带参函数的装饰
1 import time 2 def show_time2(func):# 带参数函数的装饰,修改inner的参数就好了 3 def inner(values): 4 start = time.time() 5 func(values) 6 end = time.time() 7 print('函数执行时间为;%s' % (end - start)) 8 return inner 9 @show_time2 10 def func2(values): 11 print(values) 12 time.sleep(1) 13 print('%s again' % values) 14 print(type(values)) 15 func2(123) 16 17 18 # *************************假装是分割线************************* 19 def add_show_time(func):# 带参数函数的装饰,修改inner的参数就好了 20 def inner(*args): 21 start = time.time() 22 func(*args) 23 end = time.time() 24 print('函数执行时间为;%s' % (end - start)) 25 return inner 26 @add_show_time 27 def add(*args): 28 amount = 0 29 for i in args: 30 amount += i 31 print(amount) 32 time.sleep(1) 33 return amount 34 35 add(1,2,3,4)
小结
得益于python强大的功能,python的函数可以像普通对象一样存在,可以作为参数传递给另一个函数也可以被重新赋值like
1 def func3(): 2 print('1234') 3 func3() 4 print(type(func3)) 5 6 func3 = '1234' 7 print(func3) 8 print(type(func3))
装饰器其实也是一个函数,如果难以理解,可以将其记为一种特定的格式like
装饰器将需要修饰的功能函数作为参数传入==>意味着装饰器需要接受一个参数,我们将需要修饰的函数作为参数传入
装饰器内置一个函数并返回这个内置函数
在内置函数中调用需要修饰的功能函数(这里用到了参数),并增加新功能
@show_time相当于func1 = show_time(func1)
扩展-->带参数的装饰器
1 def add_show_time(flag): 2 def show_time(func): 3 def inner(*args): 4 start = time.time() 5 func(*args) 6 end = time.time() 7 print('函数执行时间为;%s' % (end - start)) 8 print('这是装饰器传入的参数:%s' % flag) 9 return inner 10 return show_time 11 @add_show_time('Nathaniel')# 实际上就是将装饰器进行一次封装,再返回装饰器对象 12 # add = add_show_time('Nathaniel') 13 def add(*args): 14 amount = 0 15 for i in args: 16 amount += i 17 print(amount) 18 time.sleep(1) 19 return amount 20 21 add(1,2,3,4)
多次装饰
import time # 编写装饰器,为函数加上统计时间的功能 def show_time(func): def inner(*args): start_time = time.time() func(*args) end_time = time.time() number = '1998' print('add函数执行了%s' %str(end_time - start_time)) return inner # 编写装饰器,为函数加上登录功能 def login(func): def inner(*args): name = input('请输入用户名:') password = input('请输入密码:') if name == '111' and password == '111': func(*args) else:print('用户名或密码错误') return inner @login @show_time # 随便写个函数 def add(a,b): time.sleep(1) values = a + b print(values) return values add(1,2)
装饰器之登陆
需求:三个页面,进入页面之前需要登录,每个页面登录用的账号都不一样,如果输错账号密码相当于不登录,成功登录一次后再进入其他页面不需要重复登录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
userID = { '微信账户':('111','111'), 'QQ账户':('222','222'), '支付宝账户':('333','333'), } token = False def login(login_account_type): def account_type(func): def inner(): global token if not token: name = input('请输入你的%s用户名>>: ' % login_account_type).strip() password = input('请输入你的%s密码>>: ' % login_account_type).strip() if name == userID[login_account_type][0] and password == userID[login_account_type][1]: token = True func() else: print('账号或密码错误,默认等于不登录') func() else: func() return inner return account_type @login('微信账户') def page1(): # 使用微信登录 print('welcome to the page1') while True :# 输入校验,通过break choose = input('输入2进入page2,输入3进入page3,输入q退出') if choose =='q' or choose == 'Q': break if choose == '2': page2() break elif choose == '3': page3() break else: print('输入错误') @login('QQ账户') def page2(): # QQ登录 print('welcome to the page2') while True :# 输入校验,通过break choose = input('输入1进入page1,输入3进入page3,输入q退出') if choose =='q' or choose == 'Q': break if choose == '1': page1() break elif choose == '3': page3() break else: print('Invalid enter') @login('支付宝账户') def page3(): print('welcome to the page3') while True: # 输入校验,通过break choose = input('输入1进入page1,输入2进入page2,输入q退出') if choose =='q' or choose == 'Q': break if choose == '1': page1() break elif choose == '2': page2() break else: print('Invalid enter') page1()