Python基础篇【第6篇】: Python装饰器
装饰器
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
举例解释:
def func1():
some options
我们现在拥有一个已经运行了一段时间的功能函数 func1,一天我们需要一些新的功能,由于不能直接修改线上函数func1,怎么办?这时我们就可以利用装饰器。
定义一个新的装饰器函数 decorater
def auth(func):
def inner():
print "so some things here"
func()
return inner @auth
def func1():
print "this is func1 result" func1()
执行结果
so some things here
this is func1 resule
解释:装饰器函数接收被装饰的函数名称,执行内部inner函数并返回inner对应内存地址。inner函数内部函数块就可以写上新的功能。我们在进行新功能函数调用时,即可执行新功能,还不用修改原函数,用户进行调用时也不需要进行代码修改。
缺陷:无法传递参数。
装饰带参数的函数
在我们定义函数时,经常需要进行参数的传递,装饰器怎么进行装饰带参数的函数呢?将装饰器添加上函数即可!即带参数的装饰器。
def auth(func):
def inner(argv): 这里用于接收参数,以便将参数传递给后边的被装饰func函数
print "so some things here"
func(argv)
return inner @auth
def func1():
print "func1 result"
print argv func1('argv1')
执行结果:
so some things here
func1 result
argv1
同理我们如果需要传递多个参数或者动态参数时,我们在装饰器内存函数inner修改为接收多个参数或者动态参数即可。并且装饰器会自动将动态参数进行自动匹配给对应的函数。即如果有的函数不需要参数有的需要参数,我们只使用一个装饰器即可。
def decorater(func):
def inner(*args,**kwargs):
//do some options here
func(*args,**kwargs)
现在又遇到一个问题,我们的函数这里没有return值,能装饰带return的函数吗?
装饰器装饰带return函数的参数
在代码:
def auth(func):
def inner():
print "so some things here"
func()
return inner @auth
def func1():
print "this is func1 result"
return result func1()
这里的函数func1带有return函数,但在实际的操作中我们使用了装饰器以后却获取不到返回值,为什么?因为我们使用了装饰器以后我们的原函数成为了装饰器inner函数的一部分,inner函数的接收到func1的return返回值,但是inner并没有return返回,所以我们获取到的return是none。
因此只要将inner函数获取到的func1函数的return值再继续return即可获得。
多层装饰器执行顺序
当装饰器 有多层时,即多个装饰器对同一个函数进行装饰时,顺序从上到下进行执行。
装饰器函数参数
@wapper(func1,func2)
执行顺序:1. 执行wapper(func1,func2) 2. 上一步的执行结果如果等于一个目标结果如ret 3.执行@ret 装饰器
即整个过程动态生成了一个装饰器。
Python基础篇【第6篇】: Python装饰器的更多相关文章
- Python基础4 迭代器,生成器,装饰器,Json和pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- python基础之迭代器、生成器、装饰器
一.列表生成式 a = [0,1,2,3,4,5,6,7,8,9] b = [] for i in a: b.append(i+1) print(b) a = b print(a) --------- ...
- 7th,Python基础4——迭代器、生成器、装饰器、Json&pickle数据序列化、软件目录结构规范
1.列表生成式,迭代器&生成器 要求把列表[0,1,2,3,4,5,6,7,8,9]里面的每个值都加1,如何实现? 匿名函数实现: a = map(lambda x:x+1, a) for i ...
- python 基础学习笔记(8)--装饰器
**装饰器** - [ ] 装饰器和闭包有很大的联系.有时你需要在不改变源代码的情况下修改已经存在的函数.装饰器的运用可以提高效率,减少重复的代码. - [ ] 装饰器的实质是一个函数.它把一个函数作 ...
- python基础之:九步认识装饰器
step1. 先看个代码吧: def f(): ') f=lambda a:a +100 #覆盖上面的函数f print(f) #函数名指函数所在内存中的位置,入带后面括号表示执行函数 print(f ...
- python基础学习之描述符和装饰器
描述符的了解: 描述符协议: python描述符是一个"绑定行为"的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有: __get__, __set__, 和__ ...
- python基础知识---迭代器、生成器、装饰器
一.迭代器 二.生成器 http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html def func(): #定义生成器,和普通函数的区别是 ...
- python基础语法7 闭包函数与装饰器
闭包函数: 1.闭包函数必须在函数内部定义 2.闭包函数可以引用外层函数的名字 闭包函数是 函数嵌套.函数对象.名称空间与作用域 结合体. # 直接传参 def func(x): print(x) f ...
- Python 基础之面向对象之八步理解装饰器
装饰器:在不改变原有代码的情况下,为该原函数扩展新功能特征:返回新函数,替换旧函数语法:@ 语法糖 1.装饰器原型 #例1: def kuozhan(func): def newfunc(): ...
- python基础(三)闭包与装饰器
闭包(closure): 内嵌函数通过调用外部嵌套函数作用域内的变量,则这个内嵌函数就是闭包. 闭包必须满足三个条件: 必须有一个内嵌函数 内嵌函数必须引用外部嵌套函数中的变量 外部函数的返回值必须是 ...
随机推荐
- js jquery实时计算输入字符
在项目中需要倒还可以输入多少字符
- 关于ref的一点理解
先写一段代码 class Test { public int Count { get; set; } } static void Main(string[] args) { Test test = } ...
- jquery trigger-bind示例
$('#btnSearch').bind('click',function(){ .....}) 然后用trigger来激活事件:$('#btnSearch').trigger('click');
- Linux中Main函数的执行过程
1. 问题:Linux如何执行main函数. 本文使用一个简单的C程序(simple.c)作为例子讲解.代码如下, int main() { return(0); } 2. 编译 -#gcc -o ...
- input 边框颜色
border 的属性 有三个 border:5px solid red; 如果上述值缺少一个没有关系,例如border:#FF0000;是允许的. 分别对应:border-width, border- ...
- Java中抽象类和接口
抽象类: 为什么要用抽象类? 1.父类的方法好多情况下是没有内容的.例如:USB是一个父类,里面的方法的函数体是可以不写,通过子类可以重写. 2.万一子类没有重写正确,是没有没有提示的.例如:父类中函 ...
- opencv 人脸识别
背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...
- CE创建进程和线程
创建进程: HWND hWnd = NULL; PROCESS_INFORMATION pi = {}; if(NULL==hWnd) { hWnd=FindWindow(NULL,_T(" ...
- JVM加载类的过程,双亲委派机制中的方法
JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载 1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...
- range()函数的使用
坚持每天学一点,每天进步一点,迟早有一点我会成为大神. 在python中range函数可以返回一系列连续增加的整数,也是一个迭代器. 函数用法:range(开始, 结束, 步进值): #步进值默认为1 ...