装饰器基本理论

装饰器:本质就是函数,为其他函数添加附加功能

原则:1.不修改被装饰函数的源代码

        2.不修改被装饰函数的调用方式

装饰器 = 高阶函数+函数嵌套+闭包

高阶函数的定义:1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个,都可以称之为高阶函数

装饰器就是这样由来的:

import time
#想在不修改foo函数的前提下用一个函数测出foo函数执行的时间
def timer(func):
    def inner():
        start_time = time.time()
        func()
        stop_time = time.time()
        print('执行该函数用时%s'%(stop_time-start_time))
    return inner
def foo():
    time.sleep(3)
    print("执行foo函数") 
foo = timer(foo)#返回的是inner函数的地址
foo()#执行的是inner()

用@timer这个语法糖,相当于把foo = timer(foo)封装起来,提供便利

带返回值的装饰器,如果被装饰的函数有返回值,则应在装饰器函数的内层函数中定义一个值来接收被装饰函数的返回值,然后再在内层函数中将这个定义的值给返回,示例如下:

import time

def timer(func):
    def inner():
        start_time = time.time()
        res = func()
        stop_time = time.time()
        print('执行该函数用时%s'%(stop_time-start_time))
        return res
    return inner
@timer
def foo():
    time.sleep(3)
    print("执行foo函数")
    return '函数执行完毕,请执行下一事项'
res = foo()
print(res)#打印出函数执行后的返回值

带参数、返回值的装饰器:被装饰函数含有参数时,装饰函数的内层函数都需要加上参数,比如上面的例子在执行的时候实际执行的是inner()函数,所以inner()函数和其中的func函数必须要有形参,否则会报错,且在调用的时候需要加上参数。又因为被装饰函数的参数可能会发生改变,这个时候装饰器函数的参数个数也要发生改变,所以可以将装饰器函数中的参数设为不定长参数和关键字参数**kwargs(这个不知道叫的对不对),来构成通用的装饰器函数的形式,见下面的例子

import time

def timer(func):
    def inner(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('执行该函数用时%s'%(stop_time-start_time))
        return res
    return inner
@timer
def foo(name,age):
    time.sleep(3)
    print("执行foo函数,名字是%s,年龄是%d"%(name,age))
    return '函数执行完毕,请执行下一事项'
res = foo("小明",18)
print(res)#打印出函数执行后的返回值

@timer
def foo1(name,age,gender):
    time.sleep(3)
    print("执行foo函数,名字是%s,年龄是%d, 性别是%s"% (name, age,gender))
    return '函数执行完毕,请执行下一事项'
res1 = foo1("校长",38,"男")
print(res1)
 

猜你喜欢

转载自blog.csdn.net/ooxxshaso/article/details/79792555