python全栈闯关--11-装饰器初识

1、装饰器形成

当不想修改原函数,未函数前后添加功能时,就可以使用装饰器,在函数前后增加功能。

装饰器的初始形成

import time

def timer(f):
    def inner():
        print("我是装饰器,我来装饰了!!!")
        start = time.time()
        f()
        end = time.time()
        print(start - end)
    return inner  # 返回inner由于f实现了闭包,直接调用了程序

def func():
    time.sleep(1)
    print("我是小鱼,要作作作。。。有本事来装饰我!")

# 通过inner返回,在func前后进行了函数的功能的扩展
t = timer(func)
t()  # 虽然实现了功能,但是函数的调用名修改了

# 为了不改变调用名,可以赋值给func
func = timer(func)
func()  # 通过装饰器,实现了不修改函数名的装饰

语法糖

在函数前面加,加上@函数名,就可以实现装饰器,叫做语法糖

def timer(f):
    def inner():
        print("我是装饰器,我来装饰了!!!")
        start = time.time()
        f()
        end = time.time()
        print(start - end)
    return inner  # 返回inner由于f实现了闭包,直接调用了程序

@timer
def func():
    time.sleep(1)
    print("我是小鱼,要作作作。。。有本事来装饰我!")

2、带参数和返回值的装饰器

import time

def timer(f):
    def inner(a,b):  # inner接收传入的参数
        print("我是装饰器,我来装饰了!!!")
        start = time.time()
        ret = f(a,b)
        end = time.time()
        print(start - end)
        return  ("我是装饰器的返回值!!!",start - end)  # 在闭包内部,实现返回值
    return inner  # 返回inner由于f实现了闭包,直接调用了程序

@timer
def func(a,b):
    time.sleep(1)
    print("我是小鱼,要作作作。。。有本事来装饰我!")
    print("a=%s,b=%s" % (a,b))

ret = func(1,2)  # 参数相当于传递给inner
print(ret)

执行顺序

3、传递任意参数的装饰器

通过*args和**kwargs传递任意参数

def warpper(f):
    def inner(*args, **kwargs):
        ret = f(*args, **kwargs)
        return ret
    return inner

@warpper
def func(*args, **kwargs):  #*和**打散
    print("我是被装饰的函数!")
    print(args)
    print(kwargs)

func()  # 传空参数
func(1,2,3,4,b=1, a=2)  # 传任意参数
dic1 = {"a":1, "b":2}
func(*(1,2,3,4),**dic1)  # 打散传递

4、参数位置随感

个人观察结论:*是按顺序打散,形参位置:*args中,args打散后为1 2 3 4,所以args为(1,2,3,4)

def outer(*args):
    print(args)  # (1, 2, 3, 4)
    print(*args)  # 1 2 3 4  元祖被打散
    def inner(*args):
        print('innner', args)
    inner(*args)  # 打散传入inner(1,2,3,4)

outer = outer(1,2,3,4)

猜你喜欢

转载自www.cnblogs.com/zxw-xxcsl/p/11704879.html