python3装饰器-初识

装饰器的形成过程

1.函数无参数,无返回值

import time


def f1():   # 无参数,无返回值
    time.sleep(1)
    print("Hello, World!")


def timer(f):   # f 是函数名
    def inner():    # 闭包
        start = time.time()
        f()
        end = time.time()
        total = end - start
        print(total)
    return inner


f1 = timer(f1)      # 调用timer()函数,获取inner函数名指向的内存地址的返回值
f1()

2.函数有返回值,无参数

import time


def f1():   # 无参数,有返回值
    time.sleep(1)
    print("Hello, World!")
    return True


def timer(f):   # f 是函数名
    def inner():    # 闭包
        start = time.time()
        ret = f()
        end = time.time()
        total = end - start
        print(total)
        return ret
    return inner


f1 = timer(f1)      # 调用timer()函数,获取inner函数名指向的内存地址的返回值
ret = f1()
print(ret)

3.函数有参数,有返回值

 

def f1(a, **kwargs):   # 参数,返回值 *args和**args可以组成任意类型的参数
    time.sleep(1)
    print("Hello, World!", a, kwargs)
    return "abc"


def timer(f):   # f 是函数名
    def inner(*args, **kwargs):    # 闭包
        start = time.time()
        ret = f(*args, **kwargs)
        end = time.time()
        total = end - start
        print(total)
        return ret
    return inner


f1 = timer(f1)      # 调用timer()函数,获取inner函数名指向的内存地址的返回值
ret = f1(1, name='tom')
print(ret)

装饰器的作用

在不改变函数调用方式的情况下,在原函数的前后添加功能

开放封闭原则

开放:对扩展开放

封闭:对修改封闭

语法糖

简化代码

import time


def timer(f):   # f 是函数名
    def inner(*args, **kwargs):    # 闭包
        start = time.time()
        ret = f(*args, **kwargs)
        end = time.time()
        total = end - start
        print(total)
        return ret
    return inner


@timer  # f1 = timer(f1),语法糖简化代码
def f1(a, **kwargs):   # 参数,返回值 *args和**args可以组成任意类型的参数
    time.sleep(1)
    print("Hello, World!", a, kwargs)
    return "abc"


ret = f1(1, name='tom')
print(ret)

装饰器的固定模式

def wrapper(f):     # f是被装饰的函数
    def inner(*args, **kwargs):
        # 在原函数(被装饰)前增加的功能
        ret = f(*args, **kwargs)    # f是被装饰的函数
        # 在被装饰的函数后增加的功能
        return ret
    return inner


@wrapper    # 语法糖,实质 f1 = wrapper(f1)
def f1():
    print("Hello, World!")


f1()    # f1函数名指向的内存地址是:inner的函数名

巧记:1.先定义函数,再定义内部函数,返回内部函数的函数名

   2.内部函数内放被装饰的函数,传进被装饰函数的函数名

   3.被装饰的参数需要参数和返回值

猜你喜欢

转载自www.cnblogs.com/wt7018/p/10828587.html