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

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

 

一、简单的装饰器

1.为什么要使用装饰器

  装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

  装饰器的本质:就是一个闭包函数

 

       来看一个简单的装饰器:实现计算每个函数的执行时间的功能

import time def  wrapper(func):        def inner():              start=time.time()              func()              end=time.time()              print(end-start)        return inner     def  hahaha():        time.sleep(1)        print('aaaaa')hahaha=wrapper(hahaha)hahaha()
计算函数的执行时间

 

2、语法糖

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)
统计多少个函数被装饰

 

转载于:https://www.cnblogs.com/d97272015/p/8719184.html

你可能感兴趣的文章
2015第52周六
查看>>
UIScrollView设置了contentSize后还是没办法滚动?
查看>>
POJ 1205 Water Treatment Plants(递推)
查看>>
国内外DNS服务器地址列表
查看>>
买电脑之受骗经历--与诸位共享,愿诸位多一个心眼
查看>>
Lind.DDD.Authorization用户授权介绍
查看>>
counting objects in class
查看>>
上海Uber优步司机奖励政策(2月1日~2月7日)
查看>>
第二章 JVM内存分配
查看>>
Codeforces Round #272 (Div. 2)
查看>>
ThinkPHP3.2.3 自定义标签库的使用
查看>>
Activiti 5.17 实体对象与类和数据库表的映射
查看>>
【转】SVN服务器端安装、配置与管理--不错
查看>>
Fragment中的setUserVisibleHint()方法调用
查看>>
获取、增加、修改、删除sqlserver字段描述及快速查看表字段与描述
查看>>
转FTP协议详解
查看>>
js继承实例
查看>>
ABP源码分析三十八: ABP.Web.Api.OData
查看>>
[PHP] 看博客学习观察者模式
查看>>
索引失效的情况
查看>>