一、装饰器(decorators)

装饰器的语法以@开头,接着是装饰器函数的名字、可选参数。

紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下:

@decorator(dec_opt_args)
def func(func_args):
   ....

其实总体说起来,装饰器其实也就是一个函数,一个用来包装函数的函数,装饰器在函数声明完成的时候被调用,调用之后声明的函数被换成一个被装饰器装饰过后的函数。

如:

def deco(func):
   ...
   return func

@deco
def foo():
      print 'foo'
#-----------------------------------
#等价如下:
def deco(func):
   ...
   return func

def foo():
      print 'foo'

foo = deco(foo)

如下例子:

def deco1(func):
    print 'ok'
    return func

@deco1
def foo():
    print 'foo'
foo()
#输出--------------
#ok
#foo
#------------------

如果不使用装饰器,则可如下:

def deco1(func):
    print 'ok'
    return func

def foo():
    print 'foo'

print foo           #<function foo at 0x00AFE6F0>
foo = deco1(foo)
foo()
#输出--------------
#ok
#foo
#------------------

两者对比下,可发现使用装饰器是那么简便、灵活。特别是在企业级的开发上。

同时也可以多个装饰器重叠使用:

def deco1(func):
    print 'deco1'
    return func

def deco2(func):
    print 'deco2'
    return func
@deco1
@deco2
def foo():
    print 'foo'

foo()

#输出如下:-----------
#deco2
#deco1
#foo
#---------------------

等效于:

@deco1
@deco2
def foo(arg):pass
-----------与下等效----------
foo = deco1(deco2(foo()))

二、有参、无参的装饰器

上面的例子基本上都是有参数的,无参数更为简单。

1、无参

@deco1
@deco2
def foo(arg):pass
---------------------
foo = deco1(deco2(foo()))
    

2、有参

@deco1(deco_arg)
@deco2
def foo(arg):pass
---------------------
foo = deco1(deco_arg)(deco2(foo()))

返回以函数作为参数的装饰器

三、用处

1、引用日志

2、增加计时逻辑来检测性能

3、给函数加入事务的能力

四、实例

from time import ctime,sleep

def deco(func):
    def decoIn():
        print '[%s]:%s called' %(ctime(),func.__name__)
        return func
    return decoIn

@deco
def foo():
    pass

foo()
sleep(4)

for i in range(2):
    sleep(1)
    foo()

#输出如下:--------
#[Fri Jul 05 10:45:04 2013]:foo called
#[Fri Jul 05 10:45:09 2013]:foo called
#[Fri Jul 05 10:45:10 2013]:foo called
#------------------

五、强烈推荐阅读:

http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

Python入门笔记(19):Python函数(2):函数/方法装饰器的更多相关文章

  1. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  2. Python学习笔记 (4) :迭代器、生成器、装饰器、递归、正则表达式等

    迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优点是 ...

  3. Python入门笔记(22):Python函数(5):变量作用域与闭包

    一.全局变量与局部变量 一个模块中,最高级别的变量有全局作用域. 全局变量一个特征就是:除非被删除,否则他们存活到脚本运行结束,且对于所有的函数都可访问. 当搜索一个标识符(也称变量.名字等),Pyt ...

  4. Python入门笔记(21):Python函数(4):关于函数式编程的内建函数

    一.关于函数式编程的内建函数 apply()逐渐被舍弃,这里不讨论 1.filter() #filter(func,seq) """纯Python描述filter函数&q ...

  5. Python入门笔记(20):Python函数(3):关于lambda

    一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的.如下: """命名的foo函数&q ...

  6. Python入门笔记(14):Python的字符编码

    一.字符编码中ASCII.Unicode和UTF-8的区别 点击阅读:http://www.cnblogs.com/kingstarspe/p/ASCII.html 再推荐一篇相关博文:http:// ...

  7. python函数与方法装饰器

    之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...

  8. Python【第四篇】函数、内置函数、递归、装饰器、生成器和迭代器

    一.函数 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 1.定义 def 函数名(参数): ...

  9. Python 函数修饰符(装饰器)的使用

     Python 函数修饰符(装饰器)的使用 1.  修饰符的来源修饰符是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 修饰符是解决这类问题的绝佳设计, ...

随机推荐

  1. iscroll简单使用说明

    iScroll是一个高性能,资源占用少,无依赖,跨平台的javascript上拉加载,下拉刷新的滚动插件,目前版本v5.2.0. GitHub下载地址:https://github.com/cubiq ...

  2. Android 5.1 AOSP 源码获取

    本文已同步更新至:http://dxjia.cn/2015/08/android-aosp-code-sync/ Android 5.1源码开放有一个多月啦,但由于城墙的关系,每次想着更新最新源码学习 ...

  3. 防抖(Debounce)与节流( throttle)区别

    http://www.cnblogs.com/ShadowLoki/p/3712048.html http://blog.csdn.net/tina_ttl/article/details/51830 ...

  4. State状态设计模式

    1.状态模式:改变对象的行为 一个用来改变类的(状态的)对象. 2:问题:当你自己实现 State 模式的时候就会碰到很多细节的问题,你必须根据自己的需要选择合适的实现方法, 比如用到的状态(Stat ...

  5. Spring mvc4 + ActiveMQ 整合

    一.配置部分 二.代码部分 三.页面部分 四.Controller控制器 五.效果展示 六.加入监听器 七.最最重要的,别忘了打赏 一.配置部分 ActiveMQ的安装这就不说了,很简单, 这个例子采 ...

  6. URL 学习总结

    1.绝对路径(以"/"斜线开头的路径,代表相对于当前Web应用): a)地址给服务器用,web应用名称可以省略. 请求包含:request.getRequestDispatcher ...

  7. python + hadoop (案例)

    python如何链接hadoop,并且使用hadoop的资源,这篇文章介绍了一个简单的案例! 一.python的map/reduce代码 首先认为大家已经对haoop已经有了很多的了解,那么需要建立m ...

  8. Groovy split竖杆注意

    前几天将09年写的一个Asp程序使用Grails改造重写,在处理手机号码Split的时候,Asp代码: dim phoneArr phoneArr = split(phones,"|&quo ...

  9. NPM私有服务器架设 FOR CentOS

    确保计算机能够连接互连网. 一.安装 Couchdb1.6 1.(CentOS 6.7)如果版本低于6.7请使用下面命令更新系统库. yum update 2.使用下面命令安装依赖库 yum inst ...

  10. c/c++:重载 覆盖 隐藏 overload override overwrite

    http://www.cnblogs.com/qlee/archive/2011/07/04/2097055.html 成员函数的重载.覆盖与隐藏成员函数的重载.覆盖(override)与隐藏很容易混 ...