python中的装饰器
2016-06-04 11:15
399 查看
一、什么是装饰器
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。简单来讲,可以不严谨地把Python的装饰器看做一个包装函数的函数。
比如,有一个函数:
def func(): print 'func() run.' if '__main__' == __name__: func() 运行后将输出: func() run
现在需要在函数运行前后打印一条日志, 但是又不希望或者没有权限修改函数内部的结构, 就可以用到装饰器:
def log(function): def wrapper(*args, **kwargs): print 'before function [%s()] run.' % function.__name__ rst = function(*args, **kwargs) print 'after function [%s()] run.' % function.__name__ return rst return wrapper @log def func(): print 'func() run.' if '__main__' == __name__: func()
对于原来的函数"func()"并没有做修改,而是给其使用了装饰器log,运行后的输出为:
before function [func()] run. func() run. after function [func()] run. 把"@log"放到func()函数定义的地方,相当于执行了如下语句: func = log(func)
因为log()返回了一个函数, 所以原本的func指向了log()返回的函数wrapper。wrapper的参数列表为(*args, **kwargs), 所以其可以接受所有的参数调用, 在wrapper中,先打印了一行
'before function [%s()] run.' % function.__name__,然后执行了原来的函数并记录了返回值,在输出
'after function [%s()] run.' % function.__name__ ,后返回了函数的执行结果。
以下为示例:
def log(text=''): def decorator(function): @functools.wraps(function) def wrapper(*args, **kwargs): print 'before function [%s()] run, text: [%s].' % (function.__name__, text) rst = function(*args, **kwargs) print 'after function [%s()] run, text: [%s].' % (function.__name__, text) return rst return wrapper return decorator @log('log text') def func(): print 'func() run.' if '__main__' == __name__: func()View Code
输出如下:
before function [func()] run, text: [log text]. func() run. after function [func()] run, text: [log text].多层装饰器
多重装饰器的应用:当要求每一个代码块需要两个或多个检查时,这样就需要两个或多个装饰器对此代码块进行监督。 下面给出一个使用装饰器同时对代码进行登录和权限的验证:
USER_INFO={'is_login':True,'user_type':'2'} def check_login(func): def inner(*args,**kwargs): if USER_INFO.get('is_login',None): ret=func(*args,**kwargs) return ret else: print('没登录') return inner def check_admin(func): def inner(*args,**kwargs): if USER_INFO.get('user_type',None)==2: ret=func(*args,**kwargs) return ret else: print('权限不足') return inner @check_login @check_admin def index(): print('管理员') index()
相关文章推荐
- tensrflow python [defunct]
- mptt总结
- Python Flask Web 第六课 —— 静态文件
- Python中import导入上一级目录模块及循环import问题的解决
- python类4
- 搭建Python+Eclipse开发环境
- 从今天开始学习python和英语
- Python输出汉字字库及将文字转换为图片的方法
- 简易selenium自动化测试框架(Python)
- python 发送邮件实例
- 使用Python的Flask框架来搭建第一个Web应用程序
- python——template (一)
- Python 基础学习
- pip更新问题
- Python科学计算环境推荐——Anaconda
- python selenium
- Python Day4 函数 装饰器
- Scipy SVD
- Python 中的Pyc文件
- python 内置函数