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 相关文章推荐
python3.4用循环往mysql5.7中写数据并输出的实现方法
Jun 20 Python
python使用jieba实现中文分词去停用词方法示例
Mar 11 Python
python数据化运营的重要意义
Nov 25 Python
关于Pytorch的MLP模块实现方式
Jan 07 Python
如何基于Python + requests实现发送HTTP请求
Jan 13 Python
Django+boostrap 美化admin后台的操作
Mar 11 Python
python实现最速下降法
Mar 24 Python
在tensorflow以及keras安装目录查询操作(windows下)
Jun 19 Python
Django Form常用功能及代码示例
Oct 13 Python
python Cartopy的基础使用详解
Nov 01 Python
如何用tempfile库创建python进程中的临时文件
Jan 28 Python
Python 数据结构之十大经典排序算法一文通关
Oct 16 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
生成sessionid和随机密码的例子
2006/10/09 PHP
PHP简单获取视频预览图的方法
2015/03/12 PHP
PHP常见漏洞攻击分析
2016/02/21 PHP
jquery简单体验
2007/01/10 Javascript
Dom 是什么的详细说明
2010/10/25 Javascript
jquery isEmptyObject判断是否为空对象的函数
2011/02/14 Javascript
最好用的省市二级联动 原生js实现你值得拥有
2013/09/22 Javascript
JQuery球队选择实例
2015/05/18 Javascript
jQuery插件pagewalkthrough实现引导页效果
2015/07/05 Javascript
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
2016/05/24 Javascript
a标签跳转到指定div,jquery添加和移除class属性的实现方法
2016/10/10 Javascript
在js里怎么实现Xcode里的callFuncN方法(详解)
2016/11/05 Javascript
js 监控iframe URL的变化实例代码
2017/07/12 Javascript
基于Vue实现支持按周切换的日历
2020/09/24 Javascript
JavaScript面向对象精要(下部)
2017/09/12 Javascript
vue与TypeScript集成配置最简教程(推荐)
2017/10/17 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
Element-ui 自带的两种远程搜索(模糊查询)用法讲解
2021/01/29 Javascript
[01:04:31]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第二场 1月8日
2021/03/11 DOTA
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
2013/12/04 Python
python查询mysql中文乱码问题
2014/11/09 Python
在Django框架中运行Python应用全攻略
2015/07/17 Python
Python cookbook(字符串与文本)针对任意多的分隔符拆分字符串操作示例
2018/04/19 Python
django中静态文件配置static的方法
2018/05/20 Python
python实现C4.5决策树算法
2018/08/29 Python
CSS3 text shadow字体阴影效果
2016/01/08 HTML / CSS
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
JD Sports澳洲官网:英国领先的运动鞋和运动时尚零售商
2020/02/15 全球购物
信息专业本科生个人的自我评价
2013/10/28 职场文书
企业标语口号
2014/06/10 职场文书
法学自荐信
2014/06/20 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
《一面五星红旗》教学反思
2016/02/23 职场文书
如何利用STAR法则制作留学文书?
2019/08/26 职场文书