博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 装饰器
阅读量:6711 次
发布时间:2019-06-25

本文共 2855 字,大约阅读时间需要 9 分钟。

装饰器的实质就是一个函数,可以对其他函数进行装饰,在不改变原函数代码的基础上增加新的功能,调用方式也不改变。

比如我们有两个函数sout1,sout2

import timedef sout1():    time.sleep(1)    print("this is sout1")        def sout2():    time.sleep(2)    print("this is sout2")    sout1()sout2()# 输出# this is sout1# this is sout2

现在我想让每个方法执行完时输出运行需要的时间

我们可以修改代码实现

import timedef sout1():    start = time.time()    time.sleep(1)    print("this is sout1")    end = time.time()    print("running time is",end-start)        def sout2():     start = time.time()     time.sleep(2)     print("this is sout2")     end = time.time()     print("running time is",end-start) """输出this is sout1running time is 1.0009281635284424this is sout2running time is 2.0002005100250244"""

一两个这样功能简单的还能改改,但要是许多函数,新增的功能复杂怎么办?

最好使用装饰器来实现。

在使用装饰前我们要先了解两个概念 高阶函数、嵌套函数

在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:

接受一个或多个函数作为输入

输出一个函数

我们已经定义了sout1这个函数

sout1() // 会调用函数"""输出this is sout1running time is 1.0009281635284424"""print (sout)

万物皆对象嘛

所以函数也是对象

sout1存的是地址 是对象的引用

我们新增一个引用

hello = sout1hello()"""输出this is sout1running time is 1.0009281635284424"""

既然是对象 当然也能作为函数的参数和返回值

例:

def test(func):    return funcdef sout():    print("hello world!")    a = test(sout)a()"""输出hello world!"""

嵌套函数

就是函数里面又定义一个函数

例:

def outer():    print("hello")    def inner():        print("world!")    inner()outer()"""输出helloworld!"""

实现

新增功能(修改调用方式)

既然可以把函数当作参数传入,那..

我们不就可以把原有函数当作参数传进一个新的函数中,新增点功能在返回出来?

import time   def sout1():    time.sleep(1)    print("this is sout1")      def decorate(func):    start = time.time()    func()    end = time.time()    print("running time is",end-start)         decorate(sout1)      """   输出   this is sout1   running time is 1.0004260540008545   """

现在已经实现了不修改原有代码添加新功能了,但是调用方式和以前不一样了。

新增功能(不修改调用方式)

那怎么实现不修改原来的调用方式?还是sout1()进行调用?

我们已经知道函数也可以和变量一样,给它一个新的引用,进行调用

如:

x = 1y = xprint(y)"""输出1"""def sout1():    time.sleep(1)    print("this is sout1")    hello = sout1hello()"""输出this is sout1"""

那我们想办法让进行装饰的函数 decorate() 也返回一个函数

然后 sout1 = decorate(sout1)

不就实现了sout1()

新增功能而不修改原代码,原调用方式?

所以我们可以把decorate()中的代码再封装一下

def sout1():    time.sleep(1)    print("this is sout1")# 原decorate()# def decorate(func):#     start = time.time()#     func()#     end = time.time()#     print("running time is",end-start)#改为:def decorate(func):    def inner():        start = time.time()        func()        end = time.time()        print("running time is",end-start)    return innersout1 = decorate(sout1)sout1()"""输出this is sout1running time is 1.0003764629364014"""

成功!

然而我们还是要在 原来的函数调用前

添加类似语句 sout1 = decorate(sout1)

这个事情python可以通过语法糖@来帮我们完成

def decorate(func):    def inner():        start = time.time()        func()        end = time.time()        print("running time is", end - start)    return inner@decorate  # 等同于 sout1 = decorate(sout1)def sout1():    time.sleep(1)    print("this is sout1")sout1()

转载于:https://www.cnblogs.com/hehecat/p/9263202.html

你可能感兴趣的文章
java操作Excel之POI(1)
查看>>
c++中键盘的单个按键的刷新
查看>>
查找接口的实现类
查看>>
2013读书计划
查看>>
ubuntu11.10 安装reportlab出现“Python.h: 没有那个文件或目录”
查看>>
Bzoj2595: [Wc2008]游览计划
查看>>
顺序队列
查看>>
transform初学习
查看>>
Linux网络配置&进程管理
查看>>
Android 程序中禁止屏幕旋转和重启Activity
查看>>
vue-router各个属性的作用及用法
查看>>
HDU 多校1.9
查看>>
洛谷 P1177 【模板】快速排序 【快速排序/multiset排序】
查看>>
PYTHON-文件处理-练习
查看>>
AutoCompleteTextView(自动提示)
查看>>
OC-自定义构造方法
查看>>
静态链表
查看>>
Spring
查看>>
mysql实现主从复制
查看>>
深入理解C++中的Const,Mutable以及Volatile
查看>>