首页 后端开发 Python教程 使代码更简洁、更高效的基本 Python 装饰器模式

使代码更简洁、更高效的基本 Python 装饰器模式

Jan 04, 2025 am 03:25 AM

ssential Python Decorator Patterns for Cleaner, More Efficient Code

作为畅销书作家,我邀请您在亚马逊上探索我的书。不要忘记在 Medium 上关注我并表示您的支持。谢谢你!您的支持意味着全世界!

Python 装饰器是一个强大的功能,它允许我们修改或增强函数和类​​,而不改变它们的核心逻辑。作为一名开发人员,我发现掌握装饰器模式可以显着提高代码质量、可重用性和可维护性。让我们探索七种基本的装饰器模式,我发现它们在我的项目中特别有用。

类装饰器

类装饰器提供了一种修改或增强类行为和属性的方法。它们是使用类定义上方的 @decorator 语法应用的。我经常使用类装饰器来添加方法、修改现有方法或更改类属性。

这是一个向类添加新方法的类装饰器示例:

def add_greeting(cls):
    def say_hello(self):
        return f"Hello, I'm {self.name}"
    cls.say_hello = say_hello
    return cls

@add_greeting
class Person:
    def __init__(self, name):
        self.name = name

person = Person("Alice")
print(person.say_hello())  # Output: Hello, I'm Alice
登录后复制
登录后复制

在此示例中,add_greeting 装饰器向 Person 类添加了 say_hello 方法。当您想要跨多个类扩展功能而不修改其源代码时,此模式特别有用。

带参数的函数装饰器

接受参数的函数装饰器提供了更大的灵活性。它们允许我们自定义装饰器本身的行为。我发现这种模式在创建可重复使用的装饰器时非常有用,可以针对不同的用例进行微调。

这是一个可以重复函数调用指定次数的装饰器示例:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")
# Output:
# Hello, Bob!
# Hello, Bob!
# Hello, Bob!
登录后复制
登录后复制

在此示例中,repeat 装饰器接受一个参数 times 来确定应调用装饰函数的次数。这种模式为我们如何将装饰器应用到我们的函数提供了极大的灵活性。

保留函数元数据

使用装饰器时,保留原始函数的元数据很重要。这包括函数的名称、文档字符串和其他属性。 Python 标准库中的 functools.wraps 装饰器帮助我们实现了这一点。

这是一个例子:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """This is the wrapper function"""
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """This function greets someone"""
    print(f"Hello, {name}!")

say_hello("Charlie")
print(say_hello.__name__)  # Output: say_hello
print(say_hello.__doc__)   # Output: This function greets someone
登录后复制
登录后复制

通过使用@wraps(func),我们确保包装函数采用原始函数的元数据。这对于调试和内省至关重要。

堆叠多个装饰器

装饰器可以堆叠,允许将多个装饰器应用于单个函数。装饰的顺序很重要,装饰器是从下到上应用的。

这是一个例子:

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1")
        return func(*args, **kwargs)
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2")
        return func(*args, **kwargs)
    return wrapper

@decorator1
@decorator2
def greet(name):
    print(f"Hello, {name}!")

greet("David")
# Output:
# Decorator 1
# Decorator 2
# Hello, David!
登录后复制
登录后复制

在此示例中,首先应用decorator2,然后应用decorator1。使用多个装饰器时,理解执行顺序至关重要。

记忆装饰器

记忆化是一种优化技术,它存储昂贵的函数调用的结果,并在相同的输入再次出现时返回缓存的结果。我发现记忆装饰器对于提高递归函数或具有昂贵计算量的函数的性能非常有用。

这是记忆化装饰器的示例:

def add_greeting(cls):
    def say_hello(self):
        return f"Hello, I'm {self.name}"
    cls.say_hello = say_hello
    return cls

@add_greeting
class Person:
    def __init__(self, name):
        self.name = name

person = Person("Alice")
print(person.say_hello())  # Output: Hello, I'm Alice
登录后复制
登录后复制

这个记忆装饰器缓存斐波那契函数的结果,极大地提高了大输入的性能。

计时和记录装饰器

用于计时函数执行和记录函数调用的装饰器对于性能分析和调试非常有用。我在开发过程中经常使用这些。

这是组合计时和日志记录装饰器的示例:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")
# Output:
# Hello, Bob!
# Hello, Bob!
# Hello, Bob!
登录后复制
登录后复制

这个装饰器记录函数何时被调用以及执行需要多长时间。我发现这种模式对于识别代码中的性能瓶颈非常有价值。

上下文管理器装饰器

上下文管理器通常与 with 语句一起使用,以进行资源管理和错误处理。我们可以创建将函数转变为上下文管理器的装饰器,从而允许优雅的设置和拆卸操作。

这是一个例子:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """This is the wrapper function"""
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """This function greets someone"""
    print(f"Hello, {name}!")

say_hello("Charlie")
print(say_hello.__name__)  # Output: say_hello
print(say_hello.__doc__)   # Output: This function greets someone
登录后复制
登录后复制

在此示例中,file_manager 装饰器确保文件在操作后正确关闭,即使发生异常也是如此。

创建和使用装饰器的最佳实践

在与装饰者合作时,我学到了一些对我很有帮助的最佳实践:

  1. 使用 functools.wraps 保存函数元数据。
  2. 保持装饰器简单并专注于单一职责。
  3. 当您需要将参数传递给装饰器时,请使用装饰器工厂。
  4. 注意装饰器对性能的影响,特别是对于频繁调用的函数。
  5. 清楚地记录你的装饰器,解释它们的作用以及它们可能产生的任何副作用。
  6. 调试时,请记住装饰器添加了一个间接层。 Python 调试器中的 @ 语法等工具可以帮助您进入修饰函数。

测试修饰代码有时可能很棘手。我经常使用的一种方法是将装饰器与装饰函数分开测试。这允许更精细的测试和更轻松的调试。

以下是如何测试装饰器的示例:

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1")
        return func(*args, **kwargs)
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2")
        return func(*args, **kwargs)
    return wrapper

@decorator1
@decorator2
def greet(name):
    print(f"Hello, {name}!")

greet("David")
# Output:
# Decorator 1
# Decorator 2
# Hello, David!
登录后复制
登录后复制

在此测试中,我们使用模拟函数来验证我们的装饰器是否正确调用原始函数并返回其结果。

装饰器是 Python 中的一个强大工具,掌握这些模式可以显着增强您的编码能力。它们允许干净地分离关注点,促进代码重用,并且可以使您的代码更具可读性和可维护性。

我发现有效使用装饰器的关键是从简单开始,然后根据需要逐渐增加复杂性。从基本的函数装饰器开始,然后转向类装饰器和更高级的模式,例如装饰器工厂。

请记住,虽然装饰器可以极大地改进您的代码,但应谨慎使用它们。过度使用装饰器可能会导致代码难以理解和调试。始终考虑装饰器是否是适合您的特定用例的最佳解决方案。

当您继续与装饰器合作时,您可能会发现新的模式和用例。 Python 社区不断创新,新的装饰器技术定期出现。保持好奇心,尝试不同的方法,并毫不犹豫地创建自己的装饰器模式来解决项目中的独特问题。

装饰器只是 Python 中众多强大功能之一,可以帮助您编写更干净、更高效的代码。随着您对装饰器越来越熟悉,您会发现它们与其他 Python 功能(例如生成器、上下文管理器和元类)很好地集成,为优雅而强大的代码设计开辟了更多可能性。


101 本书

101 Books是一家人工智能驱动的出版公司,由作家Aarav Joshi共同创立。通过利用先进的人工智能技术,我们将出版成本保持在极低的水平——一些书籍的价格低至 4 美元——让每个人都能获得高质量的知识。

查看我们的书Golang Clean Code,亚马逊上有售。

请继续关注更新和令人兴奋的消息。购买书籍时,搜索 Aarav Joshi 以查找更多我们的书籍。使用提供的链接即可享受特别折扣

我们的创作

一定要看看我们的创作:

投资者中心 | 投资者中央西班牙语 | 投资者中德意志 | 智能生活 | 时代与回响 | 令人费解的谜团 | 印度教 | 精英开发 | JS学校


我们在媒体上

科技考拉洞察 | 时代与回响世界 | 投资者中央媒体 | 令人费解的谜团 | 科学与时代媒介 | 现代印度教

以上是使代码更简洁、更高效的基本 Python 装饰器模式的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1672
14
CakePHP 教程
1428
52
Laravel 教程
1332
25
PHP教程
1277
29
C# 教程
1256
24
Python与C:学习曲线和易用性 Python与C:学习曲线和易用性 Apr 19, 2025 am 12:20 AM

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

学习Python:2小时的每日学习是否足够? 学习Python:2小时的每日学习是否足够? Apr 18, 2025 am 12:22 AM

每天学习Python两个小时是否足够?这取决于你的目标和学习方法。1)制定清晰的学习计划,2)选择合适的学习资源和方法,3)动手实践和复习巩固,可以在这段时间内逐步掌握Python的基本知识和高级功能。

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在开发效率上优于C ,但C 在执行性能上更高。1.Python的简洁语法和丰富库提高开发效率。2.C 的编译型特性和硬件控制提升执行性能。选择时需根据项目需求权衡开发速度与执行效率。

Python vs. C:了解关键差异 Python vs. C:了解关键差异 Apr 21, 2025 am 12:18 AM

Python和C 各有优势,选择应基于项目需求。1)Python适合快速开发和数据处理,因其简洁语法和动态类型。2)C 适用于高性能和系统编程,因其静态类型和手动内存管理。

Python标准库的哪一部分是:列表或数组? Python标准库的哪一部分是:列表或数组? Apr 27, 2025 am 12:03 AM

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python:自动化,脚本和任务管理 Python:自动化,脚本和任务管理 Apr 16, 2025 am 12:14 AM

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。

科学计算的Python:详细的外观 科学计算的Python:详细的外观 Apr 19, 2025 am 12:15 AM

Python在科学计算中的应用包括数据分析、机器学习、数值模拟和可视化。1.Numpy提供高效的多维数组和数学函数。2.SciPy扩展Numpy功能,提供优化和线性代数工具。3.Pandas用于数据处理和分析。4.Matplotlib用于生成各种图表和可视化结果。

Web开发的Python:关键应用程序 Web开发的Python:关键应用程序 Apr 18, 2025 am 12:20 AM

Python在Web开发中的关键应用包括使用Django和Flask框架、API开发、数据分析与可视化、机器学习与AI、以及性能优化。1.Django和Flask框架:Django适合快速开发复杂应用,Flask适用于小型或高度自定义项目。2.API开发:使用Flask或DjangoRESTFramework构建RESTfulAPI。3.数据分析与可视化:利用Python处理数据并通过Web界面展示。4.机器学习与AI:Python用于构建智能Web应用。5.性能优化:通过异步编程、缓存和代码优

See all articles