一、什么是装饰器

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。简单来讲,可以不严谨地把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()

输出如下:

 before function [func()] run, text: [log text].
func() run.
after function [func()] run, text: [log text].

多层装饰器
多重装饰器的应用:当要求每一个代码块需要两个或多个检查时,这样就需要两个或多个装饰器对此代码块进行监督。

下面给出一个使用装饰器同时对代码进行登录和权限的验证:
 USER_INFO={'is_login':True,'user_type':''}
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()

python中的装饰器的更多相关文章

  1. 简单说明Python中的装饰器的用法

    简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下   装饰器对与 ...

  2. 【Python】python中的装饰器——@

    对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...

  3. Python 中实现装饰器时使用 @functools.wraps 的理由

    Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过  ...

  4. 写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...

  5. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...

  6. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

  7. 【Python】解析Python中的装饰器

    python中的函数也是对象,函数可以被当作变量传递. 装饰器在python中功能非常强大,装饰器允许对原有函数行为进行扩展,而不用硬编码的方式,它提供了一种面向切面的访问方式. 装饰器 一个普通的装 ...

  8. 三分钟搞定Python中的装饰器

    python的装饰器是python的特色高级功能之一,言简意赅得说,其作用是在不改变其原有函数和类的定义的基础上,给他们增添新的功能. 装饰器存在的意义是什么呢?我们知道,在python中函数可以调用 ...

  9. python cookbook 学习系列(一) python中的装饰器

    简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...

随机推荐

  1. Python的平凡之路(11)

    一. rabbitmq 1 进程Queue:  父进程与子进程进行交互,或者同属于同一父进程下多个子进程进行交互 2 队列通信:   send1.py #!/usr/bin/env python#Au ...

  2. jQueryMobile控件之ListView

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Objective C类方法load和initialize的区别

    Objective C类方法load和initialize的区别   过去两个星期里,为了完成一个工作,接触到了NSObject中非常特别的两个类方法(Class Method).它们的特别之处,在于 ...

  4. HDU 4507 吉哥系列故事——恨7不成妻

    需要推下平方和的式子..维护个数,和,平方和. #include<iostream> #include<cstdio> #include<cstring> #inc ...

  5. POJ 1236 SCC+缩点

    题意:一张有向图,一问至少给几个点发送软件,才能让所有点都能收到软件:二问是至少添加几条边才能让整个图是一个连通分量: 分析:一般求连通分量都会求缩点,在这里缩点之后,生成一张新的图,在新的图中求每一 ...

  6. M3: 将页面元素制作为图片

    本小节将介绍如何将页面元素保存为图片,在前一小节中,我们加入了名称为gridMsg的Grid Control,现在我们将使用RenderTargetBitmap把gridMsg这个页面元素保存为一张图 ...

  7. Day20_IO第二天

    1.IO体系总图 2.IO体系--字节流 记忆路线:输入输出流前面加File和Buffered,这样就全记住了 3.表达式解释 表达式:由变量和常量通过运算符连接起来的式子,单个的常量和变量也是表达式 ...

  8. 使用STL离散化

    把原来的数组a复制一份拷贝b 用sort先把数组a排序 用unique消除a里面重复的元素 对于b中的每一个元素,用lower_bound找到它在a中的位置,也就是离散化之后的编号. 没了. #inc ...

  9. 类似title的鼠标跟随事件

    $(document).ready(function(){ // 创建一个div显示提示信息 var dropTitle = document.createElement("div" ...

  10. Python asyncio库的学习和使用

    因为要找工作,把之前自己搞的爬虫整理一下,没有项目经验真蛋疼,只能做这种水的不行的东西...T  T,希望找工作能有好结果. 之前爬虫使用的是requests+多线程/多进程,后来随着前几天的深入了解 ...