无参数装饰器

对于python小白来说,python的装饰器简直让人懵逼,不知如何理解,其实按照装饰器的字面意思,

就是把自己定义的函数装饰一遍,然后返回一个新的函数(注意是新的,已经不是本来定义的函数了)

为什么这么说,我用一个装饰器最原始的例子来说明,看一下代码:

 #装饰函数
def decorator(foo):
def wrapper():
print 'wrapper'
return foo()
return wrapper #自定义函数
def abc():
print 'abc' #装饰abc
abc = decorator(abc)

以上就是装饰器的过程,可以看出调用decorator函数,返回的是wrapper函数对象,而不是abc这个函数对象,

abc这个函数在wrapper中已经是被调用了的,只是返回一个结果。以上代码的运行结果如下图,可以看出装饰

之后的abc是wrapper的函数对象,而不是原来函数了。

而python的语法糖'@'就是执行了以上的过程,下面的代码和上面的代码原理是一样的:

 def decorator(foo):
def wrapper():
print 'wrapper'
return foo()
return wrapper @decorator
def abc():
print 'abc'

python的装饰器语法就是自动调用decorator函数,并以自定义的函数abc函数对象为参数,

返回wrapper函数对象,这样一个过程。

带参数的装饰器:

接下来,再深一步来说说带参数的装饰器, 其实这个只比上面那个无参数装饰器多了一步,

就是先调用装饰器函数,再返回真正的装饰器,之后的步骤和无参数的一样了,说得太抽象?

直接上代码,这样就明显了,先调用用最外层的函数,返回的是一个真正的装饰器,然后像

之前无参数的时候一样,修饰abc函数后返回新的函数对象。

 def decoratorFunc(arg):
def decorator(foo):
def wrapper():
if arg == 0:
print 'lalala'
return foo()
return wrapper
return decorator deco0 = decoratorFunc(0)
deco1 = decoratorFunc(1) abc0 = deco0(abc)
abc1 = deco1(abc)

然后python的语法糖的过程也是像上面那样了,所以我得出一个结论,就是@后面一定是一个

函数对象,而非函数调用!

 @decoratorFunc(0)
def abc():
print 'abc'

最后

写更普通的装饰器,如果被装饰的函数有参数怎么办?很简单,利用python的可变长度参数就行。

注意,是在wrapper这个函数上我们写上python的可变长度参数,而装饰器函数decorator的参数

永远只有一个,就是函数对象。看以下代码,是无参数装饰器的例子,如果是带参数的函数,也只

需要把wrapper改成接收可变长度参数就行。

 def decorator(foo):
def wrapper(*args, **kwargs):
print 'wrapper'
return foo(*args, **kwargs)
retrun wrapper @decorator
def abc(arg):
print 'abc:', arg

作者:陈栋权

时间:2016/09/05

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,

且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

如有特别用途,请与我联系邮箱:kingchen.gd@foxmail.com

最后有兴趣的同学可以关注我的微信公众号,可以随时及时方便看我的文章。*^_^*

扫码关注或者搜索微信号:King_diary

个人关于python装饰器的白痴理解的更多相关文章

  1. Python装饰器的通俗理解

    转载:http://blog.csdn.net/u013471155 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略 ...

  2. (一)Python装饰器的通俗理解

    在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略有领悟,我希望以下的内容会对你有帮助,我也努力通过通俗的方式使得对Py ...

  3. python装饰器的简单理解

    如果你接触 Python 有一段时间了的话,想必你对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖. 装饰器的使用方法很固定: 先定义一个装饰函数(帽子)(也可以用类.偏函数实现) 再定义你 ...

  4. Python装饰器的深入理解

    装饰器 #装饰器:本质上是函数,(装饰其他函数)就是为其他函数添加附加功能 #原则: 1.不能修改被装饰的函数的源代码 # 2.不能修改被装饰的函数的调用方式 #实现装饰器知识储备 #1.函数即变量 ...

  5. python 装饰器的详细理解【多次实验】

    demo: # 装饰器其实就是对闭包的使用 print('haha嘻嘻') def hot(): print('知道') def dec(fun): print("call dec" ...

  6. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  7. 如何理解Python装饰器

    如何理解Python装饰器?很多学员对此都有疑问,那么上海尚学堂python培训这篇文章就给予答复. 一.预备知识 首先要理解装饰器,首先要先理解在 Python 中很重要的一个概念就是:“函数是 F ...

  8. 转发对python装饰器的理解

    [Python] 对 Python 装饰器的理解的一些心得分享出来给大家参考   原文  http://blog.csdn.net/sxw3718401/article/details/3951958 ...

  9. 理解 Python 装饰器看这一篇就够了

    讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它 ...

随机推荐

  1. 使用Linq动态排序

    Linq排序很方便,如果能动态创建Expression再排序就更方便了. 正序还是倒序排列 var order = typeof(Enumerable).GetMember(direction == ...

  2. 线性回归 Linear regression(1)线性回归的基本算法与求解

    本系列内容大部分来自Standford公开课machine learning中Andrew老师的讲解,附加自己的一些理解,编程实现和学习笔记. 第一章 Linear regression 1.线性回归 ...

  3. HDU1800 hash+去前导0

    注意一:卡map的时间,但是好好写+运气还是可以卡过,哇...求人品爆发 注意二:去前导0,毕竟‘0’也有ASCII码 #include<cstdio> #include<cstdl ...

  4. 揭示同步块索引(上):从lock开始

    转自:http://www.cnblogs.com/yuyijq/archive/2009/03/13/1410071.html 大家都知道引用类型对象除实例字段的开销外,还有两个字段的开销:类型指针 ...

  5. 静态分析工具PMD使用说明

    质量是衡量一个软件是否成功的关键要素.而对于商业软件系统,尤其是企业应用软件系统来说,除了软件运行质量.文档质量以外,代码的质量也是非常重要的.软件开发进行到编码阶段的时候,最大的风险就在于如何保证代 ...

  6. [CF895E]Eyes Closed

    luogu description 一个序列\(a_i\),支持一下两种操作. \(1\ \ l_1\ \ r_1\ \ l_2\ \ r_2\): 随机交换区间\([l_1,r_1]\)和\([l_ ...

  7. css 常用类名

    1.页面结构 容器: container 页头:header 内容:content/container 页面主体:main 页尾:footer 导航:nav 侧栏:sidebar 栏目:column  ...

  8. BZOJ1495 [NOI2006]网络收费

    题意 传送门 MY市NS中学,大概是绵阳市南山中学. 分析 参照Maxwei_wzj的题解. 因为成对的贡献比较难做,我们尝试把贡献算到每一个叶子节点上.我们发现按照题目中的收费方式,它等价于对于每棵 ...

  9. LG3960 列队

    题意 传送门 分析 参照博客 树状数组+离线处理即可. 利用树状数组下标本质即可\(O(\log n)\)求第k大. 代码 #include<iostream> #include<c ...

  10. YUYV&YV12&mtk6763

    stImgInOut.stImgInfo.enImageType = UV_IMAGE_TYPE_YV12; stImgInOut.stImgInfo.as32Pitch[0] = pStreamIm ...