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抓取网页中的图片示例
Feb 28 Python
探究数组排序提升Python程序的循环的运行效率的原因
Apr 01 Python
python爬虫获取淘宝天猫商品详细参数
Jun 23 Python
python提取图像的名字*.jpg到txt文本的方法
May 10 Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 Python
对python周期性定时器的示例详解
Feb 19 Python
Django 创建新App及其常用命令的实现方法
Aug 04 Python
pandas 中对特征进行硬编码和onehot编码的实现
Dec 20 Python
Python实现Wordcloud生成词云图的示例
Mar 30 Python
python线程里哪种模块比较适合
Aug 02 Python
Python调用REST API接口的几种方式汇总
Oct 19 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
Nov 27 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实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
php 启动时报错的简单解决方法
2014/01/27 PHP
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
php中字符集转换iconv函数使用总结
2014/10/11 PHP
php返回字符串中所有单词的方法
2015/03/09 PHP
PHP 双链表(SplDoublyLinkedList)简介和使用实例
2015/05/12 PHP
通过身份证号得到出生日期和性别的js代码
2009/11/23 Javascript
jquery+json实现的搜索加分页效果
2010/03/31 Javascript
图片上传判断及预览脚本的效果实例
2013/08/07 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
2014/01/10 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
JS+CSS实现的蓝色table选项卡效果
2015/10/08 Javascript
JS实现合并两个数组并去除重复项只留一个的方法
2015/12/17 Javascript
JS实现刷新父页面不弹出提示框的方法
2016/06/22 Javascript
基于jQuery的ajax方法封装
2016/07/14 Javascript
AngularJS自定义服务与fliter的混合使用
2016/11/24 Javascript
Bootstrap基本样式学习笔记之按钮(4)
2016/12/07 Javascript
浅谈es6中export和export default的作用及区别
2018/02/07 Javascript
[01:02]DOTA2辉夜杯决赛日 CDEC.Y对阵VG赛前花絮
2015/12/27 DOTA
[01:06]DOTA2小知识课堂 Ep.01 TP出门不要忘记帮队友灌瓶哦
2019/12/05 DOTA
numpy.delete删除一列或多列的方法
2018/04/03 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
Python+selenium点击网页上指定坐标的实例
2019/07/05 Python
Python中字典与恒等运算符的用法分析
2019/08/22 Python
解决Pytorch训练过程中loss不下降的问题
2020/01/02 Python
详解Python多线程下的list
2020/07/03 Python
python爬虫今日热榜数据到txt文件的源码
2021/02/23 Python
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
介绍一下grep命令的使用
2015/06/12 面试题
元宵节晚会主持人串词
2014/03/25 职场文书
文明家庭先进事迹材料
2014/05/14 职场文书
李培根演讲稿
2014/05/22 职场文书
暑期培训心得体会
2014/09/02 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
县长群众路线对照检查材料思想汇报
2014/10/02 职场文书
Java死锁的排查
2022/05/11 Java/Android