python类装饰器详解-python 中的装饰器详解
装饰器
闭包
闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包。
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 中的装饰器详解相关推荐
- python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...
第8.3节Python类的__init__方法深入剖析:构造方法与继承详解 一. 引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没 ...
- And解roid中Activity启动模式详
转自: http://www.cnblogs.com/fanchangfa/archive/2012/08/25/2657012.html And解roid中Activity启动模式详 在Androi ...
- python之33个关键字详解_Python 中的关键字 with 详解
在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...
- python关键字详解_Python 中的关键字with详解
在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...
- 技术篇|Python 类,和它在 Keras 中的使用(附代码教程)
类是 Python 语言的基本构建块之一,可应用于机器学习应用程序的开发.正如我们将看到的,用于开发类的 Python 语法很简单,可以用于在 Keras 中实现回调. 在本教程中,您将发现 Pyth ...
- python类高级用法_十.python面向对象高级用法
1.反射 1.1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的 ...
- file java详解_Java中File的实例详解
Java中File的实例详解 File 代表文件或者目录的类 构造函数 File(File parent,String child)---代表了指定父目录下的指定的子文件或者子目录 File(Stri ...
- java中final详解_Java中final用法与详解
Java中final用法与详解 final作为Java中经常用到的关键字,了解final的使用方法是非常有必要的.这里从final关键字在数据域.方法和类中三个方面分析final关键字的主要用法. f ...
- java中匿名内部类详解_java 中匿名内部类的实例详解
搜索热词 java 中匿名内部类的实例详解 原来的面貌: class TT extends Test{ void show() { System.out.println(s+"~~~哈哈&q ...
- php dump函数详解,php中var_dump()函数的详解说明
本文章给大家全面的介绍一下关于php中var_dump()函数用法详解,大家可参考参考. var_dump()void var_dump ( mixed expression [, mixed exp ...
最新文章
- ASP.NET MVC 右键点击添加没有区域(Area)、控制器、试图等选项
- Eclipse——WindowBuilder插件
- SAP Spartacus TypeScript和编译后的JavaScript命名规范
- 远程拷贝 linux服务器,linux scp 服务器远程拷贝(示例代码)
- Android快速开发框架XUtils
- JAVA链表中迭代器的实现
- 你必须掌握的常用正则表达式大全
- cisco和H3C命令对比
- Android MPush开源消息推送系统:简洁、安全、支持集群
- 晶振及其内部电路详解:
- 编译器优化级别O3引入的bug
- -webkit-touch-callout禁止长按菜单
- Lory Carousel滑块具有CSS动画和触摸支持
- bind错误:server can't find www.linuxprobe.com: SERVF
- OpenCV-Python (官方)中文教程(部分二)
- 卓克科学思维必修课0821
- 中国最大同性交友网站--Gitee入门教程
- js 监听 复制图片 拖拽上传文件 并填充到markdown编辑器
- ETH-服务节点部署(全网最新)
- 纯真IP地址库转UTFWry格式的方法
热门文章
- Unity 官方自带的例子笔记 - Space Shooter
- 每天一点小知识004--关于获取物体名字
- 2015.7.16(小高开忍住没有减仓,大盘涨3.5%,百股涨停——买进中重、中航,指导WXL错误)...
- IT行业常见职位职业路线图
- Java集合之ArrayList源码解析
- 12)登录验证函数简单编写验证
- jdbc执行Statement接口的步骤
- android发送短信
- Android 网络通信框架Volley简介(Google IO 2013)
- asp.net mvc 身份验证中返回绝对路径的ReturnUrl