python-装饰器

装饰器

基本样式

def decorator(func):
    def wrapper(*args, **kwargs):
        print("before")
        res = func(*args, **kwargs)
        print("after")
        return res
    return wrapper


@decorator
def func():
    print("hello")

func()

装饰器传参1

def decorator_factory(name):
    """装饰器工厂"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            print("before")
            res = func(*args, **kwargs)
            print("after")
            return res
        return wrapper
    # 这样就可以获取到name的值
    print(name)
    return decorator



@decorator_factory(name="随便的参数")
def func():
    print("hello")

func()

装饰器传参2

获取被装饰函数的参数
from functools import wraps
def decorator_factory(name):
    """装饰器工厂"""

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print("before")
            res = func(*args, **kwargs)
            # 这样就可以获取到args的值,下面两种方式都可以获取到
            print(a)
            print(b)
            print(args[0])
            print(args[1])
            print("after")
            return res
        return wrapper
    # 这样就可以获取到name的值
    print(name)
    return decorator



@decorator_factory(name="随便的参数")
def func(a, b):
    print("hello")
    return a + b
a = 1
b = 2
func(a, b)

@wraps用法

@wraps 装饰器的主要作用是将被装饰函数的元信息复制到装饰器函数中。这些元信息包括函数的名称、文档字符串、参数列表等。通过使用 @wraps 装饰器,可以确保装饰器函数不会改变被装饰函数的这些重要信息。

具体来说,当你使用 @wraps 装饰器装饰一个装饰器函数时,它会将被装饰函数的元信息复制到装饰器函数中。这样做的好处是,当你访问装饰器函数的属性时,你会得到和原始被装饰函数相同的结果。如果不使用 @wraps 装饰器,装饰器函数的属性可能不会和被装饰函数相匹配,这会导致一些意想不到的问题。

因此,使用 @wraps 装饰器是一个很好的习惯,特别是在编写装饰器时,这可以确保装饰的透明性和一致性。

测验:

# 编写一个装饰器,在函数执行前打印当前时间。
import time
def time_decorator(func):
    def wrapper(*args,**kargs):
        print(f"现在的时间是:{time.ctime()}")
        return func(*args,**kargs)
    return wrapper

@time_decorator
def function1():
    print("hello world")

function1()

# 编写一个装饰器,在函数执行后打印函数的返回值。
def after_decorator(func):
    def wrapper(*args,**kargs):
        res = func(*args,**kargs)
        print(f"函数的返回值是:{res}")
        return res
    return wrapper
@after_decorator
def function2(a,b):
    return a + b
function2(1,2)

# 编写一个装饰器,用于记录函数被调用的次数。
def count_decorator(func):
    count = 0
    def wrapper(*args,**kargs):
        nonlocal count # 声明为全局变量
        count += 1
        print(f"函数被调用了{count}次")
        return func(*args,**kargs)

    return wrapper
@count_decorator
def function3():
    print("hello world")

function3()
function3()

# 编写一个装饰器,用于限制函数的执行次数,达到限制次数后无法再次执行。
def warning_decorator(count):
    def decorator(func):
        def wrapper(*args, **kwargs):
            wrapper.count += 1
            if wrapper.count <= count:
                return func(*args, **kwargs)
            else:
                print("函数执行次数已达上限")
        wrapper.count = 0
        return wrapper
    return decorator

@warning_decorator(3)  # 设置上限为3次
def function4():
    print("hello world")

function4()  # 第一次调用
function4()  # 第二次调用
function4()  # 第三次调用
function4()  # 第四次调用,达到上限
posted @ 2024-05-27 15:05  沈柏军  阅读(5)  评论(0编辑  收藏  举报