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

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

装饰器函数

#装饰器:在不改变函数的调用方式的情况下,给函数的前后添加新的功能。#

有的时候写完一段代码,过段时间需要对它进行升级、添加一些新功能,但是如果要直接修改原来的代码会影响其他人的调用,所以就需要一个不修改源代码且不修改原函数的调用方式的东西,又能为原函数增添新功能的东西,装饰器就是干这个的。(装饰器的本质其实是个闭包函数)

##复习:闭包;内部函数使用外部函数中的变量,这种情况下就称这是一个闭包。

def f1(b):    def f2():        print(b)    f2()    return f2ff=f1('bbb')ff()# bbb# bbb

 

####上例中timer()就是一个装饰器函数,f()就是被装饰函数

1)为什么要用装饰器

#开放封闭原则:对修改封闭,对扩展开放

2)什么是装饰器

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

 原则: 开放封闭原则  

开放 : 对扩展是开放的    封闭 : 对修改是封闭
# timmer就是一个装饰器函数,对一个函数 有一些装饰作用
import timedef timmer(f):    #装饰器函数    def inner():        start = time.time()        ret = f()       #被装饰的函数        end = time.time()        print(end - start)        return ret    return inner@timmer         #语法糖 @装饰器函数名def func():     #被装饰的函数    time.sleep(0.01)    print('老板好同事好大家好')    return '新年好'# func = timmer(func)ret = func()   #inner()print(ret)###老板好同事好大家好0.010995864868164062新年好

3)装饰带参数函数的装饰器

import timedef timmer(f):    #装饰器函数    def inner(*args,**kwargs):        #(1,2) /(1)        start = time.time()        ret = f(*args,**kwargs)  #f(1,2)       #被装饰的函数        end = time.time()        print(end - start)        return ret    return inner@timmer         #语法糖 @装饰器函数名def func(a,b):     #被装饰的函数    time.sleep(0.01)    print('老板好同事好大家好',a,b)    return '新年好'# func = timmer(func)ret = func(1,2)   #inner()ret = func(1,b = 2)   #inner()print(ret)#####老板好同事好大家好 1 20.030028820037841797老板好同事好大家好 1 20.010994195938110352新年好

4)装饰器的固定格式

def wrapper(f):    #装饰器函数    def inner(*args,**kwargs):        '''被装饰函数之前加的内容'''        ret = f(*args,**kwargs) #被装饰的函数        '''被装饰函数之后加的内容'''        return ret    return inner@wrapper         #语法糖 @装饰器函数名def func():     #被装饰的函数    time.sleep(0.01)    print('老板好同事好大家好')    return '新年好'ret = func()
#温故而知新def wrapper(func):    def inner(*args,**kwargs): #接收参数时将参数聚合 inner((3))        print("在被装饰函数之前加的内容")        ret = func(*args,**kwargs)#调用函数时将参数打散 holiday(*(3),**{})        print("在被装饰函数之后加的内容")        return ret    return inner@wrapper # holidy = wrapper(holiday)def holiday(day):    print("全体放假%d天" %day)    return "Happy!"ret = holiday(3) #inner(3)print(ret)####在被装饰函数之前加的内容全体放假3天在被装饰函数之后加的内容Happy!

5) wraps

def span():    '''打印一个字符串的函数    ::return:    '''    print("Python_Test!")print(span.__name__) # 查看字符串格式的函数名print(span.__doc__) # document#######span打印一个字符串的函数    ::return:
################################################## from functools import wraps      #导入wraps装饰器def wrapper(func):  #func = holiday    @wraps(func)    def inner(*args,**kwargs):        print('在被装饰的函数执行之前做的事')        ret = func(*args,**kwargs)        print('在被装饰的函数执行之后做的事')        return ret    return inner@wrapper   #holiday = wrapper(holiday)def holiday(day):    '''这是一个放假通知'''    print('全体放假%s天'%day)    return '好开心'print(holiday.__name__)    #查看字符串格式的函数名print(holiday.__doc__)     #documentret = holiday(3)   #innerprint(ret) ###

holiday

这是一个放假通知
在被装饰的函数执行之前做的事
全体放假3天
在被装饰的函数执行之后做的事
好开心

###################################################

 ###三层装饰器

import timeFLAG = False                #定义全局变量def timmer_out(flag):    def timmer(func):        def inner(*args,**kwargs):            if flag:                start = time.time()                ret = func(*args,**kwargs)                end = time.time()                print(end-start)                return ret            else:                ret = func(*args, **kwargs)                return ret        return inner    return timmer# timmer = timmer_out(FLAG)@timmer_out(FLAG)    #wahaha = timmer(wahaha)def wahaha():    time.sleep(0.1)    print('wahahahahahaha')@timmer_out(FLAG)def erguotou():    time.sleep(0.1)    print('erguotoutoutou')wahaha()erguotou()

 ##温故而知新(带参数的装饰器)

import timeFLAG = Truedef timmer_out(flag):    def timmer(func):        def inner(*args,**kwargs):            if flag:                start = time.time()                ret = func(*args,**kwargs)                end = time.time()                print(end-start)                return ret            else:                ret = func(*args,**kwargs)                return ret        return inner    return timmer@timmer_out(FLAG)def func1():    time.sleep(0.1)    print("Happy1111")    return "呵呵呵!!!"@timmer_out(FLAG)def func2():    time.sleep(0.1)    print("Happy2222")    return "哈哈哈!!!"func1()func2()#####Happy11110.10094833374023438Happy22220.1000070571899414

 6)多个装饰器装饰同一个函数

def wrapper3(func):    def inner3():        print("In wrapper3 ,before func")        ret = func()        print("In wrapper3 ,after func")        return ret    return inner3@wrapper3@wrapper2@wrapper1def f():    print("This is a f")    return "万能装饰器!"print(f())###########In wrapper3 ,before funcIn wrapper2 ,before funcIn wrapper1 ,before funcThis is a fIn wrapper1 ,after funcIn wrapper2 ,after funcIn wrapper3 ,after func万能装饰器!

 

 

转载于:https://www.cnblogs.com/shaopan/p/10003966.html

你可能感兴趣的文章
轻松学PHP
查看>>
Linux中的网络监控命令
查看>>
this的用法
查看>>
windows下安装redis
查看>>
CentOS7 yum 安装git
查看>>
启动日志中频繁出现以下信息
查看>>
httpd – 对Apache的DFOREGROUND感到困惑
查看>>
分布式锁的一点理解
查看>>
idea的maven项目,install下载重复下载本地库中已有的jar包,而且下载后jar包都是lastupdated问题...
查看>>
2019测试指南-web应用程序安全测试(二)指纹Web服务器
查看>>
树莓派3链接wifi
查看>>
js面向对象编程
查看>>
Ruby中类 模块 单例方法 总结
查看>>
jQuery的validate插件
查看>>
5-4 8 管道符 作业控制 shell变量 环境变量配置
查看>>
Enumberable
查看>>
开发者论坛一周精粹(第五十四期) 求购备案服务号1枚!
查看>>
validate表单验证及自定义方法
查看>>
javascript 中出现missing ) after argument list的错误
查看>>
使用Swagger2构建强大的RESTful API文档(2)(二十三)
查看>>