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

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

一、简单的装饰器

为什么要使用装饰器呢?   装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展   装饰器的本质:就是一个闭包函数 那么我们先来看一个简单的装饰器:实现计算每个函数的执行时间的功能

import timedef wrapper(func):    def inner():        start = time.time()        func()        end = time.time()        print(end - start)    return innerdef hahaha():    time.sleep(1)    print('aaaaa')hahaha = wrapper(hahaha)hahaha()复制代码

上面的功能有点不简介,不完美,下面就引进了语法糖。

import timedef wrapper(func):    def inner():        start = time.time()        func()        end = time.time()        print(end - start)    return inner@wrapperdef kkk():  ## 相当于kkk=wrapper(kkk)    print('aaaaa')kkk()复制代码

以上的装饰器都是不带参数的函数,现在装饰一个带参数的该怎么办呢 原函数带多个参数的装饰器

import timedef timer(func):    def inner(*args,**kwargs):        start = time.time()        re = func(*args,**kwargs)        end=time.time()        print(end- start)        return re    return inner@timer   #**> func1 = timer(func1)def func1(a,b):    print('in func1')    print(a,b)@timer   #**> func1 = timer(func1)def func2(a):    print('in func2 and get a:%s'%(a))    return 'fun2 over'func1(1,2)print(func2('aaaaaa'))复制代码

带返回值的装饰器

import timedef timer(func):    def inner(*args,**kwargs):        start = time.time()        re = func(*args,**kwargs)        end=time.time()        print(end - start)        return re    return inner@timer   #**> func1 = timer(func1)def jjj(a):    print('in jjj and get a:%s'%(a))    return 'fun2 over'jjj('aaaaaa')print(jjj('aaaaaa'))复制代码

二、开放封闭原则

1.对扩展是开放的 2.对修改是封闭的

三、装饰器的固定结构

import timedef wrapper(func):  ## 装饰器    def inner(*args, **kwargs):        '''函数执行之前的内容扩展'''        ret = func(*args, **kwargs)         '''函数执行之前的内容扩展'''        return ret    return inner@wrapper  ## ****=>aaa=timmer(aaa)def aaa():    time.sleep(1)    print('fdfgdg')aaa()复制代码

四、带参数的装饰器

带参数的装饰器:就是给装饰器传参 用处: 就是当加了很多装饰器的时候,现在忽然又不想加装饰器了,想把装饰器给去掉了,但是那么多的代码,一个一个的去闲的麻烦,那么,我们可以利用带参数的装饰器去装饰它,这就他就像一个开关一样,要的时候就调用了,不用的时候就去掉了。给装饰器里面传个参数,那么那个语法糖也要带个括号。在语法糖的括号内传参。在这里,我们可以用三层嵌套,弄一个标识为去标识。如下面的代码示例

## 带参数的装饰器:(相当于开关)为了给装饰器传参## F=True#为True时就把装饰器给加上了F=False#为False时就把装饰器给去掉了def outer(flag):    def wrapper(func):        def inner(*args,**kwargs):            if flag:                print('before')                ret=func(*args,**kwargs)                print('after')            else:                ret = func(*args, **kwargs)            return ret        return inner    return wrapper@outer(F)#@wrapperdef hahaha():    print('hahaha')@outer(F)def shuangwaiwai():    print('shuangwaiwai')hahaha()shuangwaiwai()给装饰器加参数复制代码

五、多个装饰器装饰一个函数

def qqqxing(fun):    def inner(*args,**kwargs):        print('in qqxing: before')        ret = fun(*args,**kwargs)        print('in qqxing: after')        return ret    return innerdef pipixia(fun):    def inner(*args,**kwargs):        print('in qqxing: before')        ret = fun(*args,**kwargs)        print('in qqxing: after')        return ret    return inner@qqqxing@pipixiadef dapangxie():    print('饿了吗')dapangxie()'''@qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print('in qqxing: before'),然后跳到了pipixia里面的        print('in qqxing: before')        ret = fun(*args,**kwargs)        print('in qqxing: after'),完了又回到了qqqxing里面的 print('in qqxing: after')。所以就如下面的运行结果截图一样'''多个装饰器装饰一个函数复制代码

六、统计多少个函数被装饰了的小应用

l=[]def wrapper(fun):    l.append(fun)#统计当前程序中有多少个函数被装饰了    def inner(*args,**kwargs):        ## l.append(fun)#统计本次程序执行有多少个带装饰器的函数被调用了        ret = fun(*args,**kwargs)        return ret    return inner@wrapperdef f1():    print('in f1')@wrapperdef f2():    print('in f2')@wrapperdef f3():    print('in f3')print(l)复制代码

转载地址:http://zbqtx.baihongyu.com/

你可能感兴趣的文章
shell中while循环里使用ssh的注意事项
查看>>
SHELL获取计算机外网ip的几种写法
查看>>
博客正在搬迁中
查看>>
触发器与存储过程的区别
查看>>
我的友情链接
查看>>
centos搭建supervisor
查看>>
linux日志分割
查看>>
Samba再报安全漏洞
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Spring学习资料之 依赖注入(一)
查看>>
安装win7提示安装程序无法创建新的系统分区和定位现有系统分区
查看>>
快递查询接口的调用与解析案例
查看>>
我的友情链接
查看>>
服务器性能优化配置建议
查看>>
oracle sql语句实现累加、累减、累乘、累除
查看>>
SCNetworkReachabilityRef监测网络状态
查看>>
3D地图的定时高亮和点击事件(基于echarts)
查看>>
接口由40秒到200ms优化记录
查看>>
java 视频播放 多人及时弹幕技术 代码生成器 websocket springmvc mybatis SSM
查看>>