黑马程序员技术交流社区

标题: 【郑州校区】Python函数篇(5)-装饰器及实例讲解 [打印本页]

作者: 我是色色    时间: 2017-12-21 09:05
标题: 【郑州校区】Python函数篇(5)-装饰器及实例讲解
1.装饰器的概念
  装饰器本质上就是一个函数,主要是为其他的函数添加附加的功能,装饰器的原则有以下两个:
  装饰器可以简单的理解为:高阶函数+嵌套函数+闭包

2.高阶函数
  高阶函数我在前面的博客中已经讲过了,在这里我再简单的说一下吧。
  高阶函数:如果一个函数接收的参数是一个函数名,或者返回值是函数名,只要满足任意一个条件,这个函数就称为高阶函数。

3.函数嵌套
  函数嵌套:函数嵌套我在前面也已经讲过了,其实就是函数的内部再声明函数,很好理解的一个概念,举个例子:如下
[AppleScript] 纯文本查看 复制代码
def foo():
    print("the result from foo")
    def bar():
        print("the result from bar")
    bar()
foo()

  在上面这个例子中,我在函数foo()的内部又写了一个bar()函数,并在下面调用了该函数,这种方式就叫做函数嵌套,可以嵌套很多层,只要注意函数缩进问题

4.闭包
  在Python中闭包的表现形式可以理解为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
  单从上面的定义可能很难理解,我下面用一个简单的程序说明一下:
[AppleScript] 纯文本查看 复制代码
def foo():
    a=1
    b=2
    def bar():
        c=3
        return a+b+c
    return bar
print(foo()())

  在上面这个例子中,bar()就是foo()的一个内部函数,在bar()的局部作用于可以直接使用foo()的局部变量a,b,简单的说,这种内部函数可以访问外部函数变量的行为,就叫做闭包。

4.装饰器实例
  为了能让大家更好的理解装饰器,我会分步做出这个实例。
  先定义一个函数name(),3秒后打印名字
[AppleScript] 纯文本查看 复制代码
import time
def name():
    time.sleep(2)
    print("my name is 尼古拉斯赵四")
name()

  现在有一个需求,我想要统计这个函数一个运行了多少秒,在不修改源代码的情况下,就需要给这个函数写一个装饰器来完成这个需求。
[AppleScript] 纯文本查看 复制代码
def timmer(func):       #定义一个形参,就是为了接受name()这个函数,注意前面文章就已经强调过的:函数即变量---func=name
    def wapper():       #定义函数wapper(),用来接收name的参数
        start_time=time.time()
        func()          #实质上就是在运行test()      
        stop_time=time.time()
        print("name()函数一共运行了%s 秒"%(stop_time-start_time))
    return wapper      

import time
@timmer             #使用装饰器的方法,通过@+作为装饰器的那个函数名
def name():
    time.sleep(2)
    print("my name is 尼古拉斯赵四")
name()
运行结果:
my name is 尼古拉斯赵四
name()函数一共运行了2.0002381801605225 秒

  上面这个例子就是一个简单的装饰器,没有修改原函数的调用方法和返回值,装饰器timmer中用到了高阶函数+函数嵌套+闭包的知识,ok,完美。



作者: 我是楠楠    时间: 2017-12-22 15:40
{:5_229:
作者: lanqi0820    时间: 2018-5-11 18:58
我还没学到装饰器,但我接触过一点java,java中的装饰器设计模式和这个基本是一样的,面向对象的原则就是对修改封闭,对扩展开发,要为类增加功能却不修改原有的类,这个设计模式就很有用。扩展后的类接收原有类的一个对象,在扩展类内部对其功能扩展,比如说java的I/O流,在原有stream基础上增加缓冲区,就是一个新stream,这个stream具有缓冲存储的功能。
感谢你的分享,希望每天都能看到你出学习笔记,
作者: baby14    时间: 2018-6-15 07:59
多谢分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2