给一个函数增加功能有下面几种方法:
def test(): print('in the test') time.sleep(1)
1.函数调用
def timer(): start_time=time.time() test() end_time=time.time() print('the fun total time is %s' %(end_time-start_time))def test(): print('in the test') time.sleep(1)timer()
结论:改变了函数调用方式,新增timer函数,扩展test功能
2.高阶函数
import timedef timer(func): start_time=time.time() func() end_time=time.time() print('the fun total time is %s' %(end_time-start_time))def test(): print('in the test') time.sleep(1)timer(test)
结论:
改变了函数调用方式
3.装饰器
import timedef timer(fun): def wrapper(): start_time=time.time() fun() end_time=time.time() print('the fun total time is %s' %(end_time-start_time)) return wrapper@timerdef test(): print('in the test') time.sleep(1)test()
结论:
没改变原来函数调用方式
总结装饰器是一个函数=高阶函数+嵌套函数。下面更复杂一块来看下更复杂嵌套的装饰器:
不考虑session,编写一个程序模拟web验证,每个页面都需要登录后才能访问:
user = 'tianqiang'passwd = '5088'def auth(func): def wrapper(): while True: username = input('请输入登录用户名:') password = input('请输入登录密码:') if username == user and password == passwd: func() break else: print('用户鉴权失败,请重新登录') return wrapper@authdef bbs(): print('Welcome to bbs!')@authdef homepage(): print('Welcome to home!')@authdef index(): print('Welcome to index')bbs()homepage()index()
高潮版:
在上面需求的情况下,用户鉴权分为本地验证和ldap几种认证。代码如下:
user = 'tianqiang'passwd = '5088'def auth(auth_method): if auth_method =='local': def outwrapper(func): def interwrapper(): while True: username = input('请输入登录用户名:') password = input('请输入登录密码:') if username == user and password == passwd: func() break else: print('用户鉴权失败,请重新登录') return interwrapper return outwrapper elif auth_method == 'ldap': def outwrapper(func): def interwrapper(): print('ldap没有搭建好,默认全部允许登录') func() return interwrapper return outwrapper else: print('认证方式不对,退出')@auth('ldap')def bbs(): print('Welcome to bbs!')@auth('local')def homepage(): print('Welcome to home!')@auth('local')def index(): print('Welcome to index')bbs()homepage()index()