一、装饰器

  装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

  装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

  装饰器功能: 1. 自动执行装饰器函数 并且将被装饰函数当做参数对象本身,传递进去
         2. 将装饰器函数的返回值,重新赋值给被装饰的函数

用伪代码就是如下表示:

# 装饰器是一个函数,而其参数为另外一个函数
def my_shiny_new_decorator(a_function_to_decorate) : # 在内部定义了另外一个函数:一个封装器。
# 这个函数将原始函数进行封装,所以你可以在它之前或者之后执行一些代码
def the_wrapper_around_the_original_function() : # 放一些你希望在真正函数执行前的一些代码
print "Before the function runs" # 执行原始函数
a_function_to_decorate() # 放一些你希望在原始函数执行后的一些代码
print "After the function runs" #在此刻,"a_function_to_decrorate"还没有被执行,我们返回了创建的封装函数
#封装器包含了函数以及其前后执行的代码,其已经准备完毕
return the_wrapper_around_the_original_function def a_stand_alone_function() :
print "I am a stand alone function, don't you dare modify me" # 好了,你可以封装它实现行为的扩展。可以简单的把它丢给装饰器
# 装饰器本质:动态地把它和你要的代码封装起来,并且返回一个新的可用的函数。
a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#输出 :
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

二、案例

2.1 案例1.被装饰函数无参数的装饰器

 def outer(func):
def inner():
return func()
return inner def outer(func):
def inner():
print("Start")
ret = func()
print("End")
return ret
return inner @outer
def f1():
print("f1") f1() out:
Start
f1
End

从上边的案例可以看出,装饰器的本质是:自动执行装饰器函数,并且将被装饰函数当做参数对象本身,传递进去,等同于如下代码

 def f1():
print("")
def outer(xxx):
print('start')
xxx()
print('end') outer(f1) out:
start
123
end

-------等同于

 def outer(func):
return ""
@outer
def f1():
print("f1") print(f1) out: 111
# 将outer函数的return值,赋值给函数f1,这里很直白的体现了出来
 def outer(func):
def inner():
print("before")
func()
print("End")
return inner()
#在inner中,return inner() 这样会让inner直接执行,返回值就变成了None @outer
def f1():
print(123) print(f1) out:
before
123
End
None
 def outer(func):
def inner():
print("before")
r = func()
print("End")
return r
return inner
@outer
def f1():
print(123)
return "函数的返回值"
print("返回值:" ,f1()) out:
before
123
End
返回值: 函数的返回值

2.2 案例2.被装饰函数有参数的装饰器

 def outer(func):
def inner(arg):
print("before")
r = func(arg)
print("End")
return r
return inner
@outer
def f1(arg):
print(arg)
return "单参数装饰器返回值"
print("返回值:" ,f1('xxoo')) out:
before
xxoo
End
返回值: 单参数装饰器返回值

2.3 被装饰参数有多个参数装饰器

 def outer(func):
def inner(*args, **kwargs):
print("before")
r = func(*args, **kwargs)
print("End")
return r
return inner
@outer
def f1(arg1, arg2):
print(arg1, arg2)
return "多参数装饰器返回值"
print("返回值:" ,f1('xxoo', '你大爷')) out:
before
xxoo 你大爷
End
返回值: 多参数装饰器返回值

2.4 多个装饰器装饰函数

  多个装饰器装饰的话,本质和一个装饰器是一样的,记住要领:解析顺序是自下而上,执行顺序是自上而下

2.5 带参数的装饰器函数

 def Before(request,kargs):
print('before') def After(request,kargs):
print('after') def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs): before_result = before_func(request,kargs)
if(before_result != None):
return before_result; main_result = main_func(request,kargs)
if(main_result != None):
return main_result; after_result = after_func(request,kargs)
if(after_result != None):
return after_result; return wrapper
return outer @Filter(Before, After)
def Index(request,kargs):
print('index') a = Index('','')
print(a) out:
before
index
after
None

三、python内置装饰器函数  

  python还有几个内置装饰器函数分别是staticmethod、classmethod和property,作用分别是把类中定义的实例方法变成静态方法、类方法和类属性。

Python菜鸟之路:Python基础-逼格提升利器:装饰器Decorator的更多相关文章

  1. python学习之路-4 内置函数和装饰器

    本篇涉及内容 内置函数 装饰器 内置函数 callable()   判断对象是否可以被调用,返回一个布尔值 1 2 3 4 5 6 7 8 9 10 11 num = 10 print(callabl ...

  2. Python学习之路day4-函数高级特性、装饰器

    一.预备知识 学习装饰器需理解以下预备知识: 函数即变量 函数本质上也是一种变量,函数名即变量名,函数体就变量对应的值:函数体可以作为值赋给其他变量(函数),也可以通过函数名来直接调用函数.调用符号即 ...

  3. python学习之路-day2-pyth基础2

    一.        模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...

  4. Python菜鸟之路:Django 路由补充1:FBV和CBV - 补充2:url默认参数

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  5. Python基础(八)装饰器

    今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f ...

  6. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  7. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  8. python基础(八)生成器,迭代器,装饰器,递归

    生成器 在函数中使用yield关键字就会将一个普通的函数变成一个生成器(generator),普通的函数只能使用return来退出函数,而不执行return之后的代码.而生成器可以使用调用一个next ...

  9. python 装饰器(decorator)

    装饰器(decorator) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语 ...

随机推荐

  1. [转载]JAVA调用Shell脚本

    FROM:http://blog.csdn.net/jj12345jj198999/article/details/11891701 在实际项目中,JAVA有时候需要调用C写出来的东西,除了JNI以外 ...

  2. Python转码问题的解决方法

    FROM: http://www.jb51.net/article/16104.htm 在Python中,可以对String调用decode和encode方法来实现转码.     比如,若要将某个St ...

  3. CKEditor+SWFUpload实现功能较为强大的编辑器(二)---SWFUpload配置

    在前面配置完CKEditor之后,就可以拥有一个功能挺强大的编辑器了 但是现在还不够,还要能够在发表文字中插入自己电脑上的图片 CKEditor自己好像有这个功能,但是实在是...没法说,很难用(这是 ...

  4. JAVA Eclipse中如何简易的实现消息机制

    大部分情况下,我们需要实现的消息机制无非是某个类得到了数据,需要传递到某个主界面上去显示,可以把这个消息在类中做成全局变量,主界面的类用一个线程定时扫描,如果这个数据不是空,则说明被类刷新了,那么更新 ...

  5. Windows 用VS编译libevent源码

    原理:从github上克隆libevent源码,然后使用cmake生成VS工程 github 上 libevent项目地址:https://github.com/libevent/libevent 第 ...

  6. Android 四大组件学习之Server一

    上次学习了Android四大组件Activity之后,我们深刻理解了Activity.这次我们学习四大组件Service. Service与Activity的级别是一样的,都是Android系统不可缺 ...

  7. Appium Android Bootstrap源代码分析之简单介绍

    在上一个系列中我们分析了UiAutomator的核心源代码,对UiAutomator是怎么执行的原理有了根本的了解.今天我们会開始另外一个在安卓平台上基于UiAutomator的新起之秀--Appiu ...

  8. Ubuntu14.04下MySQL的安装与卸载

    转载自:https://www.2cto.com/os/201408/329502.html 安装MysQL 执行以下命令:sudo apt-get install mysql-server 2. 继 ...

  9. ClassLibary和WPF User Control LIbary和WPF Custom Control Libary的异同

    说来惭愧,接触WPF这么长时间了,今天在写自定义控件时遇到一个问题:运行界面中并没有显示自定义控件,经调试发现原来没有加载Themes中的Generic.xaml. 可是为什么在其他solution中 ...

  10. create table #temptable 临时表 和 declare @bianliang table ()表变量

    create table #temptable 临时表 和 declare @bianliang table ()表变量 在开发过程中,经常会遇到使用表变量和本地临时表的情况.下面是对二者的一个介绍: ...