首页 > 后端开发 > Python教程 > 高级 Python 装饰器:提升您的代码

高级 Python 装饰器:提升您的代码

Patricia Arquette
发布: 2025-01-06 03:42:48
原创
981 人浏览过

Advanced Python Decorators: Elevating Your Code

想象你是一个繁忙厨房里的厨师。如果你愿意的话,你有一个食谱——一个函数。随着时间的推移,您会发​​现大多数菜肴在上桌前都需要淋上一点橄榄油、少许盐或撒上香草。与其手动为每道菜添加这些最后的修饰,有一个自动应用它们的助手不是很方便吗?这正是 Python 装饰器可以为您的代码做的事情——以优雅、可重用且富有表现力的方式添加功能。

在本文中,我们将探索高级 Python 装饰器的世界。我们将超越基础知识,深入研究参数化装饰器、可堆叠装饰器,甚至带有类的装饰器。我们还将重点介绍最佳实践和要避免的陷阱。准备好?开始做饭吧!

重温基础知识

在深入探讨之前,让我们回顾一下基础知识。 Python 中的装饰器只是一个函数,它接受另一个函数(或方法)作为参数,对其进行扩充,然后返回一个新函数。这是一个例子:

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
登录后复制
登录后复制

输出:

Calling say_hello...
Hello, world!
say_hello finished.
登录后复制
登录后复制

现在,让我们进入高级用例。

参数化装饰器

有时,装饰器需要接受自己的参数。例如,如果我们想要一个装饰器来记录不同级别的消息(信息、调试、错误)怎么办?

# Parameterized decorator example
def log(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"[{level}] Calling {func.__name__}...")
            result = func(*args, **kwargs)
            print(f"[{level}] {func.__name__} finished.")
            return result
        return wrapper
    return decorator

@log("INFO")
def process_data():
    print("Processing data...")

process_data()
登录后复制

输出:

[INFO] Calling process_data...
Processing data...
[INFO] process_data finished.
登录后复制

这种分层结构(返回装饰器的函数)是创建灵活的参数化装饰器的关键。

可堆叠装饰器

Python 允许将多个装饰器应用于单个函数。让我们创建两个装饰器并将它们堆叠起来。

# Stackable decorators

def uppercase(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

def exclaim(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!!!"
    return wrapper

@uppercase
@exclaim
def greet():
    return "hello"

print(greet())
登录后复制

输出:

HELLO!!!
登录后复制

这里,装饰器以自下而上的方式应用:@exclaim 包装问候,@uppercase 包装结果。

使用类作为装饰器

Python 的一个鲜为人知的功能是类可以用作装饰器。当您需要维护状态时,这特别有用。

# Class-based decorator
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.call_count = 0

    def __call__(self, *args, **kwargs):
        self.call_count += 1
        print(f"Call {self.call_count} to {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello()
say_hello()
登录后复制

输出:

Call 1 to say_hello
Hello!
Call 2 to say_hello
Hello!
登录后复制

这里,call 方法使类能够像函数一样运行,从而允许它无缝地包装目标函数。

方法的装饰器

装饰器与类中的方法一样有效。然而,正确处理自我是至关重要的。

# Method decorator example
def log_method(func):
    def wrapper(self, *args, **kwargs):
        print(f"Method {func.__name__} called on {self}")
        return func(self, *args, **kwargs)
    return wrapper

class Greeter:
    @log_method
    def greet(self, name):
        print(f"Hello, {name}!")

obj = Greeter()
obj.greet("Alice")
登录后复制

输出:

Method greet called on <__main__.Greeter object at 0x...>
Hello, Alice!
登录后复制

将装饰器与上下文管理器相结合

有时,您需要将装饰器与资源管理集成。例如,让我们创建一个装饰器来对函数的执行进行计时。

import time

# Timing decorator
def time_it(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f} seconds")
        return result
    return wrapper

@time_it
def slow_function():
    time.sleep(2)
    print("Done sleeping!")

slow_function()
登录后复制

输出:

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
登录后复制
登录后复制

最佳实践

与装饰器合作时,保持可读性和可维护性至关重要。这里有一些提示:

  • 使用 functools.wraps:这会保留原始函数的元数据。
Calling say_hello...
Hello, world!
say_hello finished.
登录后复制
登录后复制
  • 彻底测试:装饰器可能会引入微妙的错误,尤其是在链接多个装饰器时。

  • 文档装饰器:清楚地记录每个装饰器的作用及其预期参数。

  • 避免过度使用:虽然装饰器很强大,但过度使用它们会使代码难以理解。

总结

装饰器是 Python 最具表现力的功能之一。它们允许您以干净、可重用的方式扩展和修改行为。从参数化装饰器到基于类的实现,可能性是无限的。当你磨练你的技能时,你会发现自己利用装饰器来编写更干净、更Pythonic的代码——也许,就像一位伟大的厨师一样,在你制作的每一个菜谱中创造出你的标志性风格。

注:AI辅助内容

以上是高级 Python 装饰器:提升您的代码的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板