decorator本身是一个函数,这个函数的功能是接受被修饰的函数(decorated)作为参数,返回包装函数(wrapper)替换被修饰函数(decorated)。

@decorator
func

等同于 func = decorator(func)。大部分情况下wrapper函数必须要和decorated函数具有相同的参数,这样在wrapper函数中可以执行decorated函数,并增加一些拓展流程。基于此decorator的原则如下:

  • 对于自定义decorator,wrapper函数的参数要参考目标函数设计。
  • 如果使用系统decorator,因为wrapper函数是明确的,所以目标函数的设计要参考wrapper函数的参数。

decorator接受目标函数为参数,并返回wrapper函数,因此不能接受额外的参数。为了传送额外的参数给decorator函数,可以创建decorator maker函数接受参数并返回decorator函数,然后使用decorator完成函数替换,将目标函数替换为wrapper函数。

示例:

def mydecorator_maker(*args, **kwargs):
print 'this is decorator maker function... with args %s, kwargs %s' % (args, kwargs)
def mydecorator(func):
print 'this is decorator... with args %s, kwargs %s' % (args, kwargs)
def decorator_wrapper(func_arg1, func_arg2):
print 'this is decorator wrapper, before function... with arg1 %s, arg2 %s' % (func_arg1, func_arg2)
func(func_arg1, func_arg2)
print "this is decorator wrapper, after function"
return decorator_wrapper
return mydecorator @mydecorator_maker(1, 2, 3, test='test')
def mydecorated_function(func_arg1, func_arg2):
print 'this is decorated function with arg1 %s, arg2 %s' % (func_arg1, func_arg2) mydecorated_function('lily', 'Baby')

output:

this is decorator maker function... with args (1, 2, 3), kwargs {'test': 'test'}

this is decorator... with args (1, 2, 3), kwargs {'test': 'test'}

this is decorator wrapper, before function... with arg1 lily, arg2 Baby

this is decorated function with arg1 lily, arg2 Baby

this is decorator wrapper, after function

this is decorator maker function...

这种通过一个maker函数来接受额外的参数,并且做一些额外参数的处理的实现方式非常简明。拓展一下,因为decorator的函数替换的特点,可以对decorator函数进行一次decorator来实现额外参数的处理。首先梳理一下实现逻辑:

  • decorator的原理是将被decorated函数替换为wrapper函数。wrapper函数获取decorated函数的参数,执行decorated函数并在之前之后进行业务拓展处理。
  • decorated decorator函数根据上述原理,和普通的decorator没有不同。只是在decorator上加一个decorator使其增加处理额外参数的能力。
  • decoratordecorator将原decorator函数变为一个接受参数的wrapper函数,在这个函数执行后将decorator返回。继续之前的decorator流程。
  • decoratordecorator函数中的wrapper函数与普通的wrapper函数最大的不同在于不执行decorator函数,而是返回decorator函数。因此不需要保持参数的一直,带来额外参数的支持。

    这种参数的变换不一致和上述wrapper参数保持一致的原则有悖,但是依然符合decorator进行函数替换的基本功能设计。

示例:

def decorator_decorator(decorator_to_decorated):
print 'This decorator decorator will decorate decorator passed in...'
print 'passed in decorator is %s ' % decorator_to_decorated
def decorator_wrapper(*args, **kwargs):
print 'decorator wrapper do something with args %s, kwargs %s...' % (args, kwargs)
return decorator_to_decorated
return decorator_wrapper @decorator_decorator
def decorated_decorator(func):
print 'func %s is decorated here' % func
def wrapper(func_arg1, func_arg2):
print 'wrapper with arg1 %s, args2 %s' % (func_arg1, func_arg2)
return func(func_arg1, func_arg2)
return wrapper @decorated_decorator(1, 2, 3, test='test')
def decorated_function(func_arg1, func_arg2):
print 'decorated function with func arg1 %s, arg2 %s' % (func_arg1, func_arg2)
print 'do something in decorated function' decorated_function('Liliy', 'Baby')

output:

This decorator decorator will decorate decorator passed in...

passed in decorator is <function decorateddecorator at 0x111a99c80>

decorator wrapper do something with args (1, 2, 3), kwargs {'test': 'test'}...

func <function decoratedfunction at 0x111b2bc08> is decorated here

wrapper with arg1 Liliy, args2 Baby

decorated function with func arg1 Liliy, arg2 Baby

do something in decorated function

Python Decorator分析的更多相关文章

  1. Python Decorator 和函数式编程

    看到一篇翻译不错的文章,原文链接: Python Decorator 和函数式编程

  2. Python股票分析系列——自动获取标普500股票列表.p5

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第5部分.在本教程和接下来的几节中,我们将着手研究如何为更多公司提供大量的定价信息,以及如何一次 ...

  3. Python股票分析系列——基础股票数据操作(二).p4

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第4部分.在本教程中,我们将基于Adj Close列创建烛台/ OHLC图,这将允许我介绍重新采 ...

  4. Python股票分析系列——基础股票数据操作(一).p3

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第3部分.在本教程中,我们将使用我们的股票数据进一步分解一些基本的数据操作和可视化.我们将要使用 ...

  5. Python股票分析系列——数据整理和绘制.p2

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第2部分. 在本教程中,我们将利用我们的股票数据进一步分解一些基本的数据操作和可视化. 我们将要 ...

  6. Python股票分析系列——系列介绍和获取股票数据.p1

    本系列转载自youtuber sentdex博主的教程视频内容 https://www.youtube.com/watch?v=19yyasfGLhk&index=4&list=PLQ ...

  7. Python数据采集分析告诉你为何上海二手房你都买不起

    感谢关注Python爱好者社区公众号,在这里,我们会每天向您推送Python相关的文章实战干货. 来吧,一起Python. 对商业智能BI.大数据分析挖掘.机器学习,python,R等数据领域感兴趣的 ...

  8. 【转】python模块分析之collections(六)

    [转]python模块分析之collections(六) collections是Python内建的一个集合模块,提供了许多有用的集合类. 系列文章 python模块分析之random(一) pyth ...

  9. 【转】python模块分析之unittest测试(五)

    [转]python模块分析之unittest测试(五) 系列文章 python模块分析之random(一) python模块分析之hashlib加密(二) python模块分析之typing(三) p ...

随机推荐

  1. oracle中字符串连接用||

    oracle中字符串连接用|| create or replace procedure testIf(idid number) is v_name stu.name%type; v_age stu.a ...

  2. 你注意了么?int与Integer的区别

    上次做项目时遇到了一个小问题. 我把javabean中的custid属性定义为int类型,当然与数据库中相应类型是一致的,而且在hibernate文件中配置时专门设置了not-null="f ...

  3. XHProf中文手册

    目录 导言 XHProf 概况 安装XHProf扩展 使用XHProf进行性能分析 设置XHProf用户界面 在生产环境中使用XHProf注意事项 轻量级采样模式 附加功能 信赖 鸣谢 导言 XHPr ...

  4. CSAPP学习笔记(异常控制流1)

    1:诸如子进程结束之后父进程需要被告知,有时候应用程序需要系统调用,内核通过上下文切换将控制从一个进程切换到另一个进程,还有一个进程发送信号到另一个进程时接收者转而到它的信号处理函数去执行等等,我们的 ...

  5. 团队项目建议 - 英语学习 App

    在这几年推广<构建之法>软件工程教学的过程中,我看到很多老师在讲软件工程的时候,虽然讲了很多年,但是手头没有任何项目,学生或者现想(得到一些大而无当,无法在一学期内完成一个可用版本的项目) ...

  6. Weblogic页面应用查询oracle数据库后台报错或页面日期格式显示错误

    问题:在生产环境中有两台WEB服务器,分别为227和228,部署的应用代码都是每日同步的,两边完全一致,但是某些页面查询数据时,227无结果,并且后台报java数组越界的错误,而228一切正常.经开发 ...

  7. 深入浅出讲解:php的socket通信

    对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问:1.         什么是TCP/IP.UDP?2.         Socke ...

  8. post请求接口

    /// <summary> /// post 调用接口 /// </summary> /// <param name="xmlRequest"> ...

  9. SQLserver 查看数据库包含指定数据的表(字段)

    找出所有字段 1 select a.name as columnname,object_name(a.id)as tablename into t from syscolumns a, sysobje ...

  10. laravel框架学习

    在聊技术之前,我们首先谈谈研究生的生活现状.进入到研究生忙碌的生活中,研究生是这么一个群体,外界对研究生的爱称是"研究僧",为什么我自己会觉得会是爱称.因为研究僧说的是研究生对自己 ...