在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介

因为在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中的装饰器详解相关推荐

  1. And解roid中Activity启动模式详

    转自: http://www.cnblogs.com/fanchangfa/archive/2012/08/25/2657012.html And解roid中Activity启动模式详 在Androi ...

  2. python之33个关键字详解_Python 中的关键字 with 详解

    在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...

  3. python关键字详解_Python 中的关键字with详解

    在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...

  4. python构造自定义数据包_pytorch中的自定义数据处理详解

    pytorch在数据中采用Dataset的数据保存方式,需要继承data.Dataset类,如果需要自己处理数据的话,需要实现两个基本方法. :.getitem:返回一条数据或者一个样本,obj[in ...

  5. python 消息队列 flask_python分布式爬虫中消息队列知识点详解

    当排队等待人数过多的时候,我们需要设置一个等待区防止秩序混乱,同时再有新来的想要排队也可以呆在这个地方.那么在python分布式爬虫中,消息队列就相当于这样的一个区域,爬虫要进入这个区域找寻自己想要的 ...

  6. python 类装饰器和函数装饰器区别_python进阶之装饰器之4在类中定义装饰器,将装饰器定义为类,两者的区别与联系...

    # 把装饰器定义为类 # 定义中需要实现__call__(),__get__() 方法 import types from functools import wraps class Profiled: ...

  7. java中匿名内部类详解_java 中匿名内部类的实例详解

    搜索热词 java 中匿名内部类的实例详解 原来的面貌: class TT extends Test{ void show() { System.out.println(s+"~~~哈哈&q ...

  8. file java详解_Java中File的实例详解

    Java中File的实例详解 File 代表文件或者目录的类 构造函数 File(File parent,String child)---代表了指定父目录下的指定的子文件或者子目录 File(Stri ...

  9. php dump函数详解,php中var_dump()函数的详解说明

    本文章给大家全面的介绍一下关于php中var_dump()函数用法详解,大家可参考参考. var_dump()void var_dump ( mixed expression [, mixed exp ...

  10. java中final详解_Java中final用法与详解

    Java中final用法与详解 final作为Java中经常用到的关键字,了解final的使用方法是非常有必要的.这里从final关键字在数据域.方法和类中三个方面分析final关键字的主要用法. f ...

最新文章

  1. 深度学习中的卷积网络简介
  2. LoadRunner11_录制脚本时的浏览器版本
  3. 计算机一级单元格公式设置错误是什么原因,excel表格公式出错怎么解决,电子表格求和出错...
  4. mysql 注入 绕过防火墙_绕过阿里云防火墙继续扫描探测和SQL注入
  5. datepicker不能选择是为什么_为什么客厅不好看?休闲椅选错了
  6. 乐橙本地录像回放不了_乐橙智能锁来告诉你:你家门真的安全吗?
  7. JEECG Word模板导出教程
  8. bp matlab 训练参数,基于MATLABBP神经网络设计与训练.PDF
  9. loss函数之MarginRankingLoss
  10. 如何通过索引从列表中删除元素?
  11. AngularJS自定义指令教程第2部分
  12. putty界面最友好的颜色配置参考
  13. python web工资怎么样_月薪21170的Python Web岗,学到什么程度能找到工作?
  14. 一款基于NFine.Framework升级的新框架
  15. 数据库特点分析| 寻找你心中的数据库漫威英雄
  16. 简单的 thymeleaf 前端网页模板
  17. Asp.net学习总结
  18. 酷狗音乐、QQ音乐、网易云音乐API
  19. 计算机毕业设计JAVA网上童装销售系统mybatis+源码+调试部署+系统+数据库+lw
  20. 技术人员帮助电商运营选择最合适的物流快递运输公司的5个切入点

热门文章

  1. 第1节 flume:15、flume案例二,通过自定义拦截器实现数据的脱敏
  2. 3.1.4 抽象类与归一化
  3. http head详解
  4. golang中字符串的查找方法小结
  5. C#版Windows服务安装卸载小工具-附源码
  6. 做网站用UTF-8编码还是GB2312编码?
  7. less 使用小结!笔记!
  8. Linux中last的用法及参数,查看登陆系统用户的信息
  9. HDU2502 月之数【递推】
  10. 【读书笔记】 —— 金融