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中MYSQLdb出现乱码的解决方法
Oct 11 Python
Python中利用sorted()函数排序的简单教程
Apr 27 Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 Python
python爬虫之BeautifulSoup 使用select方法详解
Oct 23 Python
python: line=f.readlines()消除line中\n的方法
Mar 19 Python
python re模块的高级用法详解
Jun 06 Python
Python中logging.NullHandler 的使用教程
Nov 29 Python
python assert的用处示例详解
Apr 01 Python
Django跨域资源共享问题(推荐)
Mar 09 Python
Python根据字符串调用函数过程解析
Nov 05 Python
Python基于百度AI实现抓取表情包
Jun 27 Python
详解MindSpore自定义模型损失函数
Jun 30 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实现加密的几种方式介绍
2015/02/22 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
2016/03/18 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
2017/10/13 PHP
对php 判断http还是https,以及获得当前url的方法详解
2019/01/15 PHP
Prototype使用指南之ajax
2007/01/10 Javascript
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
JavaScript中json使用自己总结
2013/08/13 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
2013/11/25 Javascript
jquery的each方法使用示例分享
2014/03/25 Javascript
Node.js抓取中文网页乱码问题和解决方法
2015/02/10 Javascript
JavaScript中Cookies的相关使用教程
2015/06/04 Javascript
Javascript实现快速排序(Quicksort)的算法详解
2015/09/06 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
socket.io实现在线群聊功能
2017/04/07 Javascript
解决Angular4项目部署到服务器上刷新404的问题
2018/08/31 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
详解小程序用户登录状态检查与更新实例
2019/05/15 Javascript
使用IPython下的Net-SNMP来管理类UNIX系统的教程
2015/04/15 Python
Python中的字典与成员运算符初步探究
2015/10/13 Python
利用Python读取文件的四种不同方法比对
2017/05/18 Python
浅析Git版本控制器使用
2017/12/10 Python
python下的opencv画矩形和文字注释的实现方法
2019/07/09 Python
Django ORM 自定义 char 类型字段解析
2019/08/09 Python
浅谈tensorflow中张量的提取值和赋值
2020/01/19 Python
django和flask哪个值得研究学习
2020/07/31 Python
Jupyter notebook命令和编辑模式常用快捷键汇总
2020/11/17 Python
python给list排序的简单方法
2020/12/10 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
美国香薰蜡烛品牌:PADDYWAX
2018/10/06 全球购物
中等生评语大全
2014/05/04 职场文书
关于青春的演讲稿
2014/05/05 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
运动会开幕式主持词
2015/07/01 职场文书
实习感想范文
2015/08/10 职场文书
利用Sharding-Jdbc进行分库分表的操作代码
2022/01/22 Java/Android