,

python装饰器

装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数: 多个装饰器叠加 可以同时使用多个装饰器,执行顺序为…

装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数:

def my_decorator(func):
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")
    return wrapper

# 下面的代码
def say_hello():
    print("Hello!")
say_hello = my_decorator(say_hello)

# 等效于
@my_decorator
def say_hello():
    print("Hello!")

say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后

多个装饰器叠加

可以同时使用多个装饰器,执行顺序为从下到上:

@decorator_a
@decorator_b
def func():
   pass

# 等效于:
# func = decorator_a(decorator_b(func))

实现timer装饰器

def timer(func):
    import time
    def wrapper():
        start = time.time()
        func()
        end = time.time()
        cost = end - start
        print(f"{func.__name__}  执行时间: {cost:.4f} 秒")
    return wrapper
@timer
def slow_function():
    time.sleep(1)
    return "Done"

slow_function()

实现wraps装饰器

实现wraps装饰器,用于不改变函数的名称和注释

def wraps(func):
    def decorator(wrapper):
        wrapper.__name__ = func.__name__
        wrapper.__doc__ = func.__doc__
        return wrapper
    return decorator


def my_decorator(func):
    @wraps(func)
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")

    return wrapper


@my_decorator
def say_hello():
    """打招呼"""
    print("Hello!")


say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后
print("name", say_hello.__name__)
print("doc", say_hello.__doc__)
# 输出:
# name say_hello
# doc 打招呼

实现repeat装饰器

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            t = n
            while t > 0:
                func(*args, **kwargs)
                t -= 1

        return wrapper

    return decorator


@repeat(3)
def say_hello(s):
    print(s)


say_hello(1)  # 输出: 1 1 1

实现cache装饰器

编写一个装饰器 cache,缓存函数的计算结果。当使用相同的参数调用函数时,直接返回缓存的结果:

def cache(func):
    _cache = {}

    def wrapper(*args, **kwargs):
        key = (args, tuple(kwargs.items()))
        if key not in _cache:
            _cache[key] = func(*args, **kwargs)
        return _cache[key]

    return wrapper


@cache
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)


print(fibonacci(60))  # 应该快速返回结果,输出: 9227465

提示: 使用字典存储参数到结果的映射。

实现to_dict装饰器

编写一个类装饰器 to_dict,自动为类生成 to_dict 方法,该方法可以将对象转换为字典

def to_dict(cls):
    def to_dict_method(self):
        return self.__dict__

    cls.to_dict = to_dict_method
    return cls


@to_dict
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y


p = Point(3, 4)
print(p.to_dict())  # 输出: {'x': 3, 'y': 4}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor