【Python 语法】装饰器

2024-01-15 00:00:00

目录:

获取函数运行时间

装饰器可以在不修改原函数的前提下,给原函数增加一些额外的功能,非常优雅。

如下示例: timers 装饰器给原函数 original_func 增加了计算函数运行时间的功能。

import time
from functools import wraps

def timer(func):
    @wraps(func)  # 关键:保留原函数的元信息(如名称、文档字符串)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        # 运行原函数
        result = func(*args, **kwargs)    
        end_time = time.perf_counter()
        elapsed = end_time - start_time
        print(f"函数 '{func.__name__}' 运行耗时: {elapsed:.4f} 秒")
        return result
    return wrapper

@timer
def original_func():
    time.sleep(3)

original_func()
# 输出: 函数 'original_func' 运行耗时: 3.0028 秒

不带参数的装饰器

装饰器本身也是一个函数,内部又定义了一个函数 wrapper 并将其返回,原函数在 wrapper 内部会运行,所以开发者可以在原函数运行前或运行后做一些额外操作。

def decorate_name(func):
    def wrapper(*args, **kwargs):
        print('start....')
        # 运行原函数
        r = func(*args, **kwargs)
        print('end.....')
        return r
    return wrapper

@decorate_name
def original_func():
    print('original_func....')

original_func()

运行后输出如下:

$ python test.py
start....
original_func....
end.....

带参数的装饰器

有的业务场景装饰器还可以接收参数,如下示例 decorate_name 装饰器接收一个数值参数,此时定义装饰器会多一层嵌套。

def decorate_name(n):
    def outer_wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print('装饰器参数 = {}'.format(n))
            # 运行原函数
            r = func(*args, **kwargs)
            return r
        return inner_wrapper
    return outer_wrapper

@decorate_name(1)
def original_func():
    print('original_func....')

original_func()

# 装饰器参数 = 1
# original_func....

示例

from datetime import datetime

def print_func_args(func):
    """
    装饰器: 打印方法参数
    """
    def wrapper(*args, **kwargs):
        print('function params  args: {}, kwargs: {}'.format(args, kwargs))
        r = func(*args, **kwargs)
        return r
    return wrapper


def print_func_return(func):
    """
    装饰器: 打印方法返回值
    """
    def wrapper(*args, **kwargs):
        r = func(*args, **kwargs)
        print('function return  {}'.format(r))
        return r
    return wrapper


def print_func_time(func):
    """
    装饰器: 打印方法执行时间
    """
    def wrapper(*args, **kwargs):
        start_time = datetime.now()
        r = func(*args, **kwargs)
        end_time = datetime.now()
        time = end_time - start_time
        print('function time    {}'.format(time))
        return r
    return wrapper


def print_func_info(func):
    """
    装饰器: 打印方法参数、返回值、执行时间
    """
    def wrapper(*args, **kwargs):
        start_time = datetime.datetime.now()
        r = func(*args, **kwargs)
        end_time = datetime.datetime.now()
        time = end_time - start_time
        print('function params  args: {}, kwargs: {}'.format(args, kwargs))
        print('function return  {}'.format(r))
        print('function time    {}'.format(time))
    return wrapper


@print_func_time
@print_func_return
@print_func_args
def add(a, b):
    return a + b


add(1, 2)
# 输出: 
# function params  args: (1, 2), kwargs: {}
# function return  3
# function time    0:00:00.000040

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: