python的装饰器

装饰器的语法

在函数之前 + @ 装饰器的名字

装饰器作用

在不更改原功能函数内部代码,并且不改变调用方法的情况下为原代码添加新的功能

常见的定义形式

1、闭包(最常见的形式)
    使用的场景:在不更改原功能函数代码的基础上,进行功能的扩展
    通用的写法:
        def decorate(func):
            def wrapper(*args, **kwargs):
                print("在原功能函数执行前扩展的代码1")
                print("在原功能函数执行前扩展的代码2")
                # 调用原功能函数,并接受返回值
                result = func(*args, **kwargs)
                print("在原功能函数执行后扩展的代码1")
                print("在原功能函数执行后扩展的代码2")
                # 返回被装饰函数执行的结果
                return result
            return wrapper
2、普通函数
    一般用于给被装饰的函数(类),进行属性添加或者修改
        def decorate(func):
            # 装饰器内部的功能代码
            return func
3、类

装饰器的副作用

# 通过闭包形式的装饰器装饰函数之后,原函数名指向的是闭包中的函数,无法再获取原函数的文档注释和函数名
from functools import wraps


def decorate(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("在原功能函数执行前扩展的代码1")
        print("在原功能函数执行前扩展的代码2")
        # 调用原功能函数,并接受返回值
        result = func(*args, **kwargs)
        print("在原功能函数执行后扩展的代码1")
        print("在原功能函数执行后扩展的代码2")
        # 返回被装饰函数执行的结果
        return result

    return wrapper


@decorate
def work(a, b):
    """
    :param a:参数a的描述
    :param b: 参数b的描述
    :return: 返回值的描述
    """
    print("-----work-----")


print(work.__doc__)
print(work.__name__)

带参数的装饰器

from functools import wraps


def decorate(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("在原功能函数执行前扩展的代码1")
        print("在原功能函数执行前扩展的代码2")
        # 调用原功能函数,并接受返回值
        result = func(*args, **kwargs)
        print("在原功能函数执行后扩展的代码1")
        print("在原功能函数执行后扩展的代码2")
        # 返回被装饰函数执行的结果
        return result

    return wrapper


def add_name(name):
    print("参数name的值为:", name)
    return decorate


@add_name('小明')
def work(a, b):
    return a + b


work(1, 2)

# 合并之后
    print("参数name的值为:", name)

    def decorate(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print("在原功能函数执行前扩展的代码1")
            print("在原功能函数执行前扩展的代码2")
            # 调用原功能函数,并接受返回值
            result = func(*args, **kwargs)
            print("在原功能函数执行后扩展的代码1")
            print("在原功能函数执行后扩展的代码2")
            # 返回被装饰函数执行的结果
            return result

        return wrapper

    return decorate
    # 第一层接收装饰器的参数
    # 第二层接收被装饰器的函数
    # 第三层接收被装饰器的函数的参数

@add_name('小明')
def work(a, b):
    return a + b


work(1, 2)

实例1

实现一个可以统计任意函数执行时间的装饰器

import time


def count_time(func):
    """
    :param func:接受到的是被装饰的函数
    :return:
    """

    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        print("执行时间为:", end_time - start_time)
    return wrapper


@count_time
def work1():
    for i in range(3):
        time.sleep(1)
    print("-----work1-----执行完毕")

@count_time
def work2():
    for i in range(2):
        time.sleep(1)
    print("-----work2-----执行完毕")


work1()
work2()

实例2

def deco(func):
    func.name = "小柠檬"
    return func


@deco
def work():
    print("123456")


print(work.name)
posted @   NikeAirBall  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示