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实现给字典添加条目的方法
Sep 25 Python
分析用Python脚本关闭文件操作的机制
Jun 28 Python
Python使用pymongo库操作MongoDB数据库的方法实例
Feb 22 Python
Django 开发环境与生产环境的区分详解
Jul 26 Python
Python实现二叉搜索树BST的方法示例
Jul 30 Python
python程序 线程队列queue使用方法解析
Sep 23 Python
python判断无向图环是否存在的示例
Nov 22 Python
python实现数据清洗(缺失值与异常值处理)
Dec 02 Python
使用 Python 清理收藏夹里已失效的网站
Dec 03 Python
pytorch 中pad函数toch.nn.functional.pad()的用法
Jan 08 Python
Python 实现黑客帝国中的字符雨的示例代码
Feb 20 Python
Python字符串对齐方法使用(ljust()、rjust()和center())
Apr 26 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 删除数组元素
2009/01/16 PHP
PHP 基于文件头的文件类型验证类函数
2012/05/01 PHP
php二维数组用键名分组相加实例函数
2013/11/06 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
JS对象转换为Jquery对象实现代码
2013/12/29 Javascript
js实现编辑div节点名称的方法
2014/12/17 Javascript
JavaScript设计模式之单件模式介绍
2014/12/28 Javascript
使用JS实现图片展示瀑布流效果的实例代码
2016/09/12 Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
2017/01/17 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
2018/02/26 Javascript
JavaScript引用类型Function实例详解
2018/08/09 Javascript
jQuery实现的淡入淡出图片轮播效果示例
2018/08/29 jQuery
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
2020/05/18 Javascript
vue实现图书管理系统
2020/12/29 Vue.js
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
[54:57]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第二场 1月8日
2021/03/11 DOTA
python pandas实现excel转为html格式的方法
2018/10/23 Python
利用python实现简易版的贪吃蛇游戏(面向python小白)
2018/12/30 Python
django ajax发送post请求的两种方法
2020/01/05 Python
Matplotlib绘制雷达图和三维图的示例代码
2020/01/07 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
使用python实现飞机大战游戏
2020/03/23 Python
浅谈css3中calc在less编译时被计算的解决办法
2017/12/04 HTML / CSS
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
Maisons du Monde德国:法国家具和装饰的市场领导者
2019/07/26 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
shell程序如何生命变量?shell变量是弱变量吗?
2014/11/10 面试题
中学生在校期间的自我评价分享
2013/11/13 职场文书
预防传染病方案
2014/06/14 职场文书
怎样写辞职信
2015/02/27 职场文书
详解python的内存分配机制
2021/05/10 Python
详解python字符串驻留技术
2021/05/21 Python
java设计模式--原型模式详解
2021/07/21 Java/Android
浅谈redis的过期时间设置和过期删除机制
2022/03/18 MySQL