Python3_装饰器

1、装饰器的定义

装饰器本质上就是一个函数,功能是为其他函数添加功能

装饰器的原则:

  • 不修改被装饰函数的源代码
  • 不修改被装饰函数的调用方式

2、装饰器的知识储备

先声明一点:装饰器=高阶函数+函数嵌套+闭包

2.1、高阶函数

定义:

  • 函数的参数是一个函数
  • 函数的返回值是一个函数

2.2、嵌套函数

定义:

  • 在一个函数的内部又定义一个函数

注:在嵌套函数中外部的函数称为外函数,在函数内部定义的函数称为内函数

2.3、闭包

定义:

  • 内函数调用外函数的临时变量
  • 外函数的返回值是内函数的引用

代码示例:

def test(a, b):
    def test2():
        print(a + b)
    return test2

res = test(1, 2)
res()  # 相当于调用test2()

3、装饰器

3.1、装饰器的基本语法格式

通过上面已经知道了 装饰器=高阶函数+函数嵌套+闭包,下面来实现一下装饰器

使用装饰器统计函数test运行的时间

import time


def timer(func):
    '计算程序运行时间的函数'
    def count():
        start_time = time.time()
        func()
        end_time = time.time()
        print("运行的时间是%s" % (end_time - start_time))
    return count


@timer      # @timer就是相当与执行了timer(test)()
def test():
    time.sleep(3)
    print("函数test运行结束")

运行时间:

函数test运行结束

运行的时间是3.0005695819854736

3.2、函数加上返回值

当我们在test函数中加上一个return返回值的时候会发现在调用test函数的时候并没有返回值,原因是函数test是在装饰器函数的内函数中运行的,在内函数中并没有return值,修改如下:

import time
def timer(func):
    def count():
        start_time = time.time()
        res = func()
        print(res)
        end_time = time.time()
        print("运行的时间是%s" %(end_time - start_time))
    return count

@timer
def test():
    time.sleep(3)
    print("函数test运行结束")
    return "这是test的返回值"

test()

3.3、函数加上参数

当对test函数加上参数的时候会发现代码报错,原因是在装饰器的内函数中我们并没有给定形参,导致test在内函数中运行时无法接收相应的实参;修改如下:

import time
def timer(func):
    def count(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        print(res)
        end_time = time.time()
        print("运行的时间是%s" %(end_time - start_time))
    return count

@timer
def test(name, age):
    time.sleep(3)
    print("函数test运行结束")
    print("名字 【%s】,年龄【%s】" %(name, age))
    return "这是test的返回值"

test("xiaoming", 20)

运行结果:

函数test运行结束

名字 【xiaoming】,年龄【20】

这是test的返回值

运行的时间是3.0006966590881348

3.4、给装饰器函数加上参数

如果需要给用户选择test函数是否要统计运行时间的话就要给装饰器添加一个参数,判断是否要统计test运行的时间;可使用闭包

情况1:需要进行运算时间的统计

import time
def auth(para = True):
    def timer(func):
        def count(*args, **kwargs):
            if para == True:
                start_time = time.time()
                res = func(*args, **kwargs)
                print(res)
                end_time = time.time()
                print("运行的时间是%s" %(end_time - start_time))
            else:
                func(*args, **kwargs)
        return count
    return timer

@auth(para=True)
def test(name, age):
    time.sleep(3)
    print("函数test运行结束")
    print("名字 【%s】,年龄【%s】" %(name, age))
    return "这是test的返回值"

test("xiaoming", 20)

运行结果:

函数test运行结束

名字 【xiaoming】,年龄【20】

这是test的返回值

运行的时间是3.0004258155822754

情况2:不需要进行运算时间的统计

import time
def auth(para = True):
    def timer(func):
        def count(*args, **kwargs):
            if para == True:
                start_time = time.time()
                res = func(*args, **kwargs)
                print(res)
                end_time = time.time()
                print("运行的时间是%s" %(end_time - start_time))
            else:
                func(*args, **kwargs)
        return count
    return timer

@auth(para=False)
def test(name, age):
    time.sleep(3)
    print("函数test运行结束")
    print("名字 【%s】,年龄【%s】" %(name, age))
    return "这是test的返回值"

test("xiaoming", 20)

运行结果:

函数test运行结束

名字 【xiaoming】,年龄【20】

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 要点: 函数式编程:注意不是“函数编程”,多了一个“式” 模块:如何使用模块 面向对象编程:面向对象的概念、属性、...
    victorsungo阅读 1,617评论 0 6
  • 函数 什么是函数? 将具有某种功能的代码放到一起, 构成一个函数.为什么说函数? 因为需要研究一个问题, 函数可以...
    DragonFangQy阅读 960评论 0 2
  • 在过往的十八年的时光里,常常以为自己在年幼的时候经历过的不好的事情已然被忘却在了记忆的犄角旮旯之中,覆满灰...
    瘾肆阅读 256评论 1 4
  • …嗯…… 啊…… 啊…词语…的动感…吖…! ……您在哪儿…… …快到我…笔尖…来吧… …滴答…嘀嗒… …滴… …眼...
    神道仙灵阅读 164评论 0 0
  • 这几天被一位同事的事迹震撼到了,以至心情久久不能平静,谨以此文感慨之。——题记 我的这位同事是一名90后,安徽人氏...
    夏湄月阅读 550评论 6 5