day04 装饰器

一、装饰器出现的背景:

  对前面已经投入生成的程序(由函数构成)进行扩展,但是不能改变原先函数的源码以及调用方式。

二、源码

  1、decorator1.py

#现在要给每个函数添加一个功能:显示每个函数的执行时间,但是每个函数的源码不能改变,以及每个函数的调用方式不能改变。
#(试想你的雇主用了你的第一版函数,想试试第二版,但调用的地方太多了,如果一一改变,太麻烦)
#那么装饰器是个不错的选择

import time

# def addRunTime(func):
#
#     startTime = time.time()
#     func()
#     endTime=time.time()
#     print('time is %f' % (endTime-startTime))
#     return func

def addRunTime(func):           #这个函数的取名和你要添加的功能有关
    def decorator():            #注意这个子函数,和上一版(已经注释了的)的区别
        #print(decorator)
        #print(func)
        startTime = time.time()
        func()
        endTime=time.time()
        print('the running time of ' + func.__name__ + ' is %f' % (endTime - startTime))
    return decorator

@addRunTime         #等价与    function1=addRunTime(function1)
def function1():
    time.sleep(1);
    print('in the function1')

@addRunTime
def function2():
    time.sleep(1);
    print('in the function2')

function1()
'''
执行流程:addRunTime(function1)
'''
function2()

     2、decorator2.py

'''
    给带有形参的函数扩展功能:这里在decorator1的基础上,给每个函数添加参数
'''

import time

def addRunTime(func):
    def decorator(*args,**kwargs):      #实参实际传入到这个函数
        #print(decorator)
       # print(func)
        startTime = time.time()
        func(*args,**kwargs)
        endTime=time.time()
        print('the running time of '+func.__name__+' is %f' % (endTime-startTime))
    return decorator

@addRunTime
def function1(arg1):
    time.sleep(1);
    print("in the function1 arg1=",arg1)


# arg1+**kaargs 函数调用的时候,参数必须使用 “arg1="shabi1",arg2="shabi2",arg3='shabi3'”形式给出
#且第一个实参 必须是arg1=xxx  ,函数会把第一个参数赋值给arg1,其余的参数放在一个字典的形式给kwargs
@addRunTime
def function2(arg1,*args):
    time.sleep(1);
    print("in the function2 arg1=%s,args=%s" %(arg1,args))


#*args,**kwargs,函数调用的时候,参数可以是任意数字,字符串,列表,字典,元组的组成,key=value的实参必须放在最后面
#函数会把所有的非 key=value的放在一个元组里面传给args,而把所有的key=value参数放在一个字典里面传给kwargs
@addRunTime
def function3(*args,**kwargs):
    time.sleep(1);
    print("in the function3 args=%s,kwargs=%s" %(args,kwargs))


function1('shabi1')
function2('shabi2','shabi3')
function3(1,2,[3,4],arg1='shabi1',arg2='shabi2')

  3、decorator3.py

'''
   是否扩展可以选择(可以扩展,也可以不扩展):这里在decorator2的基础上,通过ifAdd的值来确定是否扩展功能
'''
import time

def ifAddRunTime(ifAdd):
    def addRunTime(func):
        def decorator(*args,**kwargs):
            if ifAdd==True:
                startTime = time.time()
                func(*args,**kwargs)
                endTime=time.time()
                print('the running time of '+func.__name__+' is %f' % (endTime-startTime))
            else:
                func(*args, **kwargs)
        return decorator
    return addRunTime       #这个return 别忘了,  记住语法糖的等价形式, 如果没有返回值,会报错

@ifAddRunTime(True)
def function1(arg1):
    time.sleep(1);
    print("in the function1 arg1=",arg1)

@ifAddRunTime(False)
def function2(arg1,*args):
    time.sleep(1);
    print("in the function2 arg1=%s,args=%s" %(arg1,args))

@ifAddRunTime(True)
def function3(*args,**kwargs):
    time.sleep(1);
    print("in the function3 args=%s,kwargs=%s" %(args,kwargs))

#现在要给每个函数添加一个功能:显示每个函数的执行时间,但是每个函数的调用方式不能改变。(试想你的雇主用了你的第一版函数,想试试第二版,但调用的地方太多了,如果一一改变,太麻烦)
#那么装饰器是个不错的选择

function1('shabi1')
function2('shabi2','shabi3')
function3(1,2,[3,4],arg1='shabi1',arg2='shabi2')

  4、decorator4.py

'''
   保留函数的返回值,这里是在decorator3的基础上,保留了函数的返回值
'''
import time

def ifAddRunTime(ifAdd):
    def addRunTime(func):
        def decorator(*args,**kwargs):
            if ifAdd==True:
                startTime = time.time()
                funcValue=func(*args,**kwargs)
                endTime=time.time()
                print('the running time of '+func.__name__+' is %f' % (endTime-startTime))
                return funcValue
            else:
                return func(*args, **kwargs)
        return decorator
    return addRunTime       #这个return 别忘了,  记住语法糖的等价形式, 如果没有返回值,会报错

@ifAddRunTime(True)
def function1(arg1):
    time.sleep(1);
    print("in the function1 arg1=",arg1)
    return 1

@ifAddRunTime(False)
def function2(arg1,*args):
    time.sleep(1);
    print("in the function2 arg1=%s,args=%s" %(arg1,args))
    return 2

@ifAddRunTime(True)
def function3(*args,**kwargs):
    time.sleep(1);
    print("in the function3 args=%s,kwargs=%s" %(args,kwargs))
    return 3

#现在要给每个函数添加一个功能:显示每个函数的执行时间,但是每个函数的调用方式不能改变。(试想你的雇主用了你的第一版函数,想试试第二版,但调用的地方太多了,如果一一改变,太麻烦)
#那么装饰器是个不错的选择

print(function1('shabi1'))
function2('shabi2','shabi3')
function3(1,2,[3,4],arg1='shabi1',arg2='shabi2')

 

posted @ 2018-01-21 14:52  XiaoBBai  阅读(147)  评论(0编辑  收藏  举报