装饰器

闭包

闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包。

def decorator(par): #定义一个外部函数

def wrapper(kkk): #定义一个内部函数

test = par + kkk #内部函数使用了外部函数的参数

print(test)

return wrapper #返回了内部函数的引用

if __name__ == "__main__":

tt = decorator('mmm')

tt('nnn')

# 输出结果

# mmmnnn

装饰器

python 中的装饰器用@符号来表名,常见的代码是在函数名字上面@classmethod,@+函数名是python中的一种语法糖,因为解释器会对这种语法做特殊处理。

@decorator #等价于 func = decorator(func)

def func():

pass

下面通过代码简单说一下装饰器

def decorator(func):

def wrapper():

print("装饰前------decorator---")

func()

print("装饰后------decorator---")

return wrapper

def decorator1(func):

def wrapper1():

print("装饰前-----decorator1***********")

func()

print("装饰后-----decorator1*********")

return wrapper1

@decorator #等价于 test = decorator(test)

def test():

print('test-------')

def test1():

print('test1*******')

#等价于 test3 = decorator1(test3),括号里test3等于下面等号左边的test3

@decorator1

@decorator #等价于 test3 = decorator(test3)

def test3():

print('test3&&&&&&&')

if __name__ == "__main__":

test()

test1 = decorator(test1)

test1()

test3()

输出结果如下:

装饰前------decorator---

test-------

装饰后------decorator---

装饰前------decorator---

test1*******

装饰后------decorator---

装饰前-----decorator1***********

装饰前------decorator---

test3&&&&&&&

装饰后------decorator---

装饰后-----decorator1*********

上面代码简单说明了装饰器的作用和实现原理,当有多个装饰器同时对一个函数进行装饰时,先装饰内层然后装饰外层

函数实现装饰器

函数的装饰器分为两种情况:被装饰的函数带有参数和返回值,装饰器带有参数,下面通过代码对这两种情况进行说明:

被装饰函数带有参数和返回值

def pre_decorator(par='pre_dec')

def decorator(fun):

def dec_fun(*args, **kwargs): #可变参数

print("装饰器的参数---%s" % pre)

print("装饰前-----------")

ret = fun(*args, **kwargs) #函数执行的地方

print("装饰后-----------")

return ret #被装饰函数没有返回值的时候为None

return dec_fun

return decorator

@decorator

def sum(a,b,c):

print('执行函数')

return a+b+c

if __name__ == "__main__":

test = sum(2,3,6)

print(test)

输出结果:

装饰前-----------

执行函数

装饰后-----------

11

函数装饰器带有参数

在阅读一些开源框架的代码的时候,经常会遇到装饰器带有参数,带有参数的装饰器能够进一步丰富装饰器的功能,当装饰器含有参数时,我们要想获取并利用装饰器的参数,需要在原来装饰器基础上再封装一层闭包,请看下面代码

def pre_decorator(par='pre_dec'): # 装饰器添加一个默认字符串

def decorator(fun):

def dec_fun(*args, **kwargs): # 可变参数

print("装饰器的参数---%s" % par)

print("装饰前-----------")

ret = fun(*args, **kwargs) # 函数执行的地方

print("装饰后-----------")

return ret # 被装饰函数没有返回值的时候为None

return dec_fun

return decorator

@pre_decorator('haha')

def sum(a,b,c):

print('执行函数')

return a+b+c

if __name__ == "__main__":

test = sum(2,3,6)

输出结果:

装饰器的参数---haha

装饰前-----------

执行函数

装饰后-----------

类实现装饰器

类装饰器不带有参数 和 带有参数,其实现方式有点区别

当类装饰器不带有参数

class Decorator(object):

def __init__(self, func):

self.func = func

def __call__(self, *args, **kwargs):

print('装饰前----------')

ret = self.func(*args, **kwargs)

print('装饰后----------')

return ret

# 当装饰器没有参数时,其本质还是等价于 sum = Decorator(sum),被装饰函数sum引用传到__init__()中

# 相当于实例化一个对象,对象后面加括号比如sum(), 要调用类中的__call__()

@Decorator # 相当于sum = Decorator(sum)

def sum(a, b, c):

print('执行函数--------')

return a+b+c

if __name__ == "__main__":

print(sum(1,2,3))

运行结果:

装饰前----------

执行函数--------

装饰后----------

6

类装饰器含有参数时

class Decorator(object):

def __init__(self, par=''):

self.par = par

print('类装饰器的参数是 %s' % self.par)

# 被装饰函数的引用传到__call__中,需要通过闭包来装饰

def __call__(self, func):

def dec_fun(*args, **kwargs):

print('装饰前----------')

ret = func(*args, **kwargs)

print('装饰后----------')

return ret

return dec_fun

# 当类装饰器含有参数时,其本质等价于 sum = Decorator(par='parameter')(sum)

# 那么此时装饰器的参数par='parameter'传到了__init__()中,而被装饰函数sum的引

# 用传到了__call__()中了

@Decorator(par='parameter') # 相当于 sum = Decorator(par='parameter')(sum)

def sum(a, b, c):

print('执行函数--------')

return a+b+c

if __name__ == "__main__":

print(sum(1,2,3))

输出结果:

类装饰器的参数是 parameter

装饰前----------

执行函数--------

装饰后----------

6

python类装饰器详解-python 中的装饰器详解相关推荐

  1. python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...

    第8.3节Python类的__init__方法深入剖析:构造方法与继承详解 一.    引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没 ...

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

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

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

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

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

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

  5. 技术篇|Python 类,和它在 Keras 中的使用(附代码教程)

    类是 Python 语言的基本构建块之一,可应用于机器学习应用程序的开发.正如我们将看到的,用于开发类的 Python 语法很简单,可以用于在 Keras 中实现回调. 在本教程中,您将发现 Pyth ...

  6. python类高级用法_十.python面向对象高级用法

    1.反射 1.1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的 ...

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

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

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

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

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

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

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

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

最新文章

  1. ASP.NET MVC 右键点击添加没有区域(Area)、控制器、试图等选项
  2. Eclipse——WindowBuilder插件
  3. SAP Spartacus TypeScript和编译后的JavaScript命名规范
  4. 远程拷贝 linux服务器,linux scp 服务器远程拷贝(示例代码)
  5. Android快速开发框架XUtils
  6. JAVA链表中迭代器的实现
  7. 你必须掌握的常用正则表达式大全
  8. cisco和H3C命令对比
  9. Android MPush开源消息推送系统:简洁、安全、支持集群
  10. 晶振及其内部电路详解:
  11. 编译器优化级别O3引入的bug
  12. -webkit-touch-callout禁止长按菜单
  13. Lory Carousel滑块具有CSS动画和触摸支持
  14. bind错误:server can't find www.linuxprobe.com: SERVF
  15. OpenCV-Python (官方)中文教程(部分二)
  16. 卓克科学思维必修课0821
  17. 中国最大同性交友网站--Gitee入门教程
  18. js 监听 复制图片 拖拽上传文件 并填充到markdown编辑器
  19. ETH-服务节点部署(全网最新)
  20. 纯真IP地址库转UTFWry格式的方法

热门文章

  1. Unity 官方自带的例子笔记 - Space Shooter
  2. 每天一点小知识004--关于获取物体名字
  3. 2015.7.16(小高开忍住没有减仓,大盘涨3.5%,百股涨停——买进中重、中航,指导WXL错误)...
  4. IT行业常见职位职业路线图
  5. Java集合之ArrayList源码解析
  6. 12)登录验证函数简单编写验证
  7. jdbc执行Statement接口的步骤
  8. android发送短信
  9. Android 网络通信框架Volley简介(Google IO 2013)
  10. asp.net mvc 身份验证中返回绝对路径的ReturnUrl