装饰器

装饰器模式(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装饰器的更多相关文章

  1. Python基础4 迭代器,生成器,装饰器,Json和pickle 数据序列化

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  2. 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) --------- ...

  3. 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 ...

  4. python 基础学习笔记(8)--装饰器

    **装饰器** - [ ] 装饰器和闭包有很大的联系.有时你需要在不改变源代码的情况下修改已经存在的函数.装饰器的运用可以提高效率,减少重复的代码. - [ ] 装饰器的实质是一个函数.它把一个函数作 ...

  5. python基础之:九步认识装饰器

    step1. 先看个代码吧: def f(): ') f=lambda a:a +100 #覆盖上面的函数f print(f) #函数名指函数所在内存中的位置,入带后面括号表示执行函数 print(f ...

  6. python基础学习之描述符和装饰器

    描述符的了解: 描述符协议: python描述符是一个"绑定行为"的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有: __get__, __set__, 和__ ...

  7. python基础知识---迭代器、生成器、装饰器

    一.迭代器 二.生成器 http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html def func(): #定义生成器,和普通函数的区别是 ...

  8. python基础语法7 闭包函数与装饰器

    闭包函数: 1.闭包函数必须在函数内部定义 2.闭包函数可以引用外层函数的名字 闭包函数是 函数嵌套.函数对象.名称空间与作用域 结合体. # 直接传参 def func(x): print(x) f ...

  9. Python 基础之面向对象之八步理解装饰器

    装饰器:在不改变原有代码的情况下,为该原函数扩展新功能特征:返回新函数,替换旧函数语法:@ 语法糖 1.装饰器原型 #例1: def kuozhan(func):    def newfunc():  ...

  10. python基础(三)闭包与装饰器

    闭包(closure): 内嵌函数通过调用外部嵌套函数作用域内的变量,则这个内嵌函数就是闭包. 闭包必须满足三个条件: 必须有一个内嵌函数 内嵌函数必须引用外部嵌套函数中的变量 外部函数的返回值必须是 ...

随机推荐

  1. 用GO扫描图片像素,复制图片

    关键是使用image.image/png.image/color包 // main.go package main import ( "fmt" "bufio" ...

  2. JUCE 界面库显示中文乱码问题

    JUCE 界面库显示中文乱码问题 环境: Windows7 64位 旗舰版 Visual Studio Ultimate 2012 JUCE 4.1 问题描述: 直接使用juce::String存储中 ...

  3. 图片轮播(bootstrap)与 圆角搜索框(纯css)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  4. JDBC连接数据库演示

    今天重新学习了JDBC连接数据库,使用的数据库是Oracle,在运行前已经手动建立了一张t_user表,建表信息如下: create table t_user( card_id ) primary k ...

  5. 随机生成UUID(GUID)的方法

    - (NSString *)UUID { CFUUIDRef uuid_ref = CFUUIDCreate(NULL); CFStringRef uuid_string_ref= CFUUIDCre ...

  6. 【转】Web Service单元测试工具实例介绍之SoapUI

    转自:http://blog.csdn.net/oracle_microsoft/article/details/5689585 SoapUI 是当前比较简单实用的开源Web Service 测试工具 ...

  7. linux创建静态库

    [1]新建源程序staticlib.c /************************************************************************* > ...

  8. C++联合体(union)

    C++的union本质上也是个类,跟struct性质几乎一致但是有一个最大的区别,数据共享内存 说到共享内存就要说下union的内存分配 union的大小是按照union里面的成员内存的最大值而分配的 ...

  9. phpstorm version 2016.2 License Server激活

    phpstorm version 2016.2 License Server激活 安装后,在激活的时候选择 license server; 输入如下地址激活: http://jetbrains.ten ...

  10. Android Context 上下文 你必须知道的一切

    本文转载于:http://blog.csdn.net/lmj623565791/article/details/40481055 转载请标明出处:http://blog.csdn.net/lmj623 ...