python中的装饰器详解


Posted in Python onApril 13, 2015

在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介

因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收的参数是函数对象,然后动态地函数参数添加额外的功能,而不用修改原有的函数对象.python装饰器传入的参数是函数,返回的值也是函数!
python装饰器思想有点类似设计模式的装饰模式, 其意图是动态地给函数对象添加额外的功能.比如像增加日志打印的功能,有点面向切面编程(AOP)的感觉.
装饰器语法

以@开头,接着后面跟着的是装饰器的名字和可选的参数.装饰器语法是一种语法糖.
格式如下

@decomaker(deco_args)

    def foo(func_opt_args)

可以组合,等价于foo = g(f(foo))
@g

@f

def foo():

    statement

简单装饰器

实例

#!/usr/bin/python

def  deco(func):

    print 'start'

    func()

    print 'end'

    return func
@deco

def foo():

    print 'In foo'
foo()

foo()

输出
start

In foo

end

In foo

In foo

带内嵌函数装饰器

内嵌函数保证每次新函数都被调用.而且被装饰的函数可以带有参数.
实例

def  deco(func):

    def _deco(x):    #该函数为内嵌函数

        print 'start'

        func(x)

        print 'end' 

    return _deco
@deco

def foo(x):

    print 'In foo, get value is: %d' % x
foo(123456)

输出:
start

In foo, get value is: 123456

end

带参数的装饰器

需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。简单的说来:foo=decomaker(deco_args)(foo)

实例

def deco(arg):

    def wrapper1(func):

        def _deco(x):

            print "get type is: ", arg

            func(x)

        return _deco
    def wrapper2(func):

        def _deco(x):

            func(x)

            print "get type is: ", arg

        return _deco
    if arg == 'type1':

        return wrapper1

    else:

        return wrapper2
@deco("type2")

def foo(x):

    print 'In foo: ', x
foo(123)

输出
In foo:  123

get type is:  type2

总结

装饰器本质是高阶的函数,可以装饰其他函数,增加被装饰函数的功能,但不能覆盖或改变被装饰函数原有的行为.对于被装饰的函数来说,装饰器是透明的.装饰器传入参数为函数,返回的函数是被装饰的函数.最后我们来实现给一个函数添加打印日志的功能,而不用改变这个函数.

#!/usr/bin/python

#coding=utf-8

import functools
def log(prefix, suffix):

    def deco(func):

        @functools.wraps(func)

        def wrapper(*args, **kargs):

            print '%s log start' % prefix

            print('get a is: %s' % args[0])

            print('get b is: %s' % args[1])

            print('get c is: %s' % args[2])

            print('get d is: %s' % kargs['d'])

            print('get d is: %s' % kargs['f'])

            func(*args, **kargs)

            print '%s log end' % suffix

        return wrapper

    return deco
@log('logstart', 'logend')

def test(a, b, c, d, f):

    print 'call func name is: %s' % test.__name__
test(1, 2, 3, d = 'dddd', f = 'ffff')

输出:
logstart log start

get a is: 1

get b is: 2

get c is: 3

get d is: dddd

get d is: ffff

call func name is: test

logend log end
Python 相关文章推荐
Python命令行参数解析模块optparse使用实例
Apr 13 Python
简单介绍Python中利用生成器实现的并发编程
May 04 Python
Python中死锁的形成示例及死锁情况的防止
Jun 14 Python
Python3的urllib.parse常用函数小结(urlencode,quote,quote_plus,unquote,unquote_plus等)
Sep 18 Python
python利用正则表达式排除集合中字符的功能示例
Oct 10 Python
Python设置在shell脚本中自动补全功能的方法
Jun 25 Python
Python字符串内置函数功能与用法总结
Apr 16 Python
JAVA SWT事件四种写法实例解析
Jun 05 Python
实例讲解Python 迭代器与生成器
Jul 08 Python
使用Python判断一个文件是否被占用的方法教程
Dec 16 Python
python 高阶函数简单介绍
Feb 19 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 Python
Python生成器(Generator)详解
Apr 13 #Python
Python中函数的多种格式和使用实例及小技巧
Apr 13 #Python
在Python中使用SimpleParse模块进行解析的教程
Apr 11 #Python
Python的动态重新封装的教程
Apr 11 #Python
简单的Python的curses库使用教程
Apr 11 #Python
详解Python中的文本处理
Apr 11 #Python
状态机的概念和在Python下使用状态机的教程
Apr 11 #Python
You might like
php设计模式 Adapter(适配器模式)
2011/06/26 PHP
php地址引用(php地址引用的效率问题)
2012/03/23 PHP
php实现简易聊天室应用代码
2015/09/23 PHP
php上传图片获取路径及给表单字段赋值的方法
2016/01/23 PHP
PHP编程获取各个时间段具体时间的方法
2017/05/26 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
js的表单操作 简单计算器
2011/12/29 Javascript
学习JavaScript设计模式(继承)
2015/11/26 Javascript
详解基于Bootstrap扁平化的后台框架Ace
2015/11/27 Javascript
Bootstrap布局方式详解
2016/05/27 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
2016/05/30 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
2016/07/07 Javascript
html+javascript+bootstrap实现层级多选框全层全选和多选功能
2017/03/09 Javascript
JS实现留言板功能
2017/06/17 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
Vue插槽原理与用法详解
2019/03/05 Javascript
详解微信小程序获取当前时间及日期的方法
2019/04/28 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
利用python微信库itchat实现微信自动回复功能
2017/05/18 Python
基于python中staticmethod和classmethod的区别(详解)
2017/10/24 Python
python 将有序数组转换为二叉树的方法
2019/03/26 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
Sofmap官网:日本著名的数码电器专卖店
2017/05/19 全球购物
实习教师个人的自我评价
2013/11/08 职场文书
工程师岗位职责
2013/11/08 职场文书
大学团支书的自我评价分享
2013/12/14 职场文书
小学语文教学反思
2014/02/10 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
销售团队激励口号
2014/06/06 职场文书
七夕情人节促销方案
2014/06/07 职场文书
建筑工地大门标语
2014/06/18 职场文书
党员自我对照检查材料
2014/08/19 职场文书
2014年保育员个人工作总结
2014/12/02 职场文书
Python内置数据结构列表与元组示例详解
2021/08/04 Python