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的urllib库提交WEB表单
Feb 24 Python
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
May 06 Python
Python中for循环控制语句用法实例
Jun 02 Python
python中正则的使用指南
Dec 04 Python
Python实现的插入排序算法原理与用法实例分析
Nov 22 Python
python实现将文件夹内的每张图片批量分割成多张
Jul 22 Python
python实现静态服务器
Sep 05 Python
python飞机大战pygame游戏框架搭建操作详解
Dec 17 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
Jan 07 Python
如何用Anaconda搭建虚拟环境并创建Django项目
Aug 02 Python
Python实现中英文全文搜索的示例
Dec 04 Python
python 离散点图画法的实现
Apr 01 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
使用Apache的htaccess防止图片被盗链的解决方法
2013/04/27 PHP
PHP自动生成缩略图函数的源码示例
2019/03/18 PHP
解决laravel session失效的问题
2019/10/14 PHP
laravel清除视图缓存的代码
2019/10/23 PHP
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
2008/11/24 Javascript
javascript 使td内容不换行不撑开
2012/11/29 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
基于JavaScript自定义构造函数的详解说明
2013/04/24 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
JavaScript学习笔记--常用的互动方法
2016/12/07 Javascript
详解使用nvm管理多版本node的方法
2017/08/30 Javascript
详解React Native顶|底部导航使用小技巧
2017/09/14 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
vue项目中axios使用详解
2018/02/07 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
JavaScript设计模式之模板方法模式原理与用法示例
2018/08/07 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
2018/09/02 Javascript
详解50行代码,Node爬虫练手项目
2019/04/22 Javascript
微信小程序 调用微信授权窗口相关问题解决
2019/07/25 Javascript
vue实现标签云效果的方法详解
2019/08/28 Javascript
解决elementui表格操作列自适应列宽
2020/12/28 Javascript
批处理与python代码混合编程的方法
2016/05/19 Python
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
对Python中画图时候的线类型详解
2019/07/07 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
PyTorch 普通卷积和空洞卷积实例
2020/01/07 Python
解决python3.6用cx_Oracle库连接Oracle的问题
2020/12/07 Python
美国婚戒购物网站:Anjays Designs
2017/06/28 全球购物
Yves Rocher伊夫·黎雪美国官网:法国始创植物美肌1959
2019/01/09 全球购物
自我鉴定范文300字
2013/10/01 职场文书
幼儿园义卖活动方案
2014/01/17 职场文书
2015欢度元旦标语口号
2014/12/09 职场文书
党员干部公开承诺书范文
2015/04/27 职场文书
2015选调生工作总结
2015/07/24 职场文书
个人合作协议范本
2015/08/06 职场文书