探索Python中的装饰器:提升代码效率与可读性

简介: 【10月更文挑战第3天】 本文将深入探讨Python中装饰器的使用方法及其背后的原理。通过实例展示如何利用装饰器简化代码、提高可读性,并介绍一些高级用法。无论您是编程新手还是经验丰富的开发者,都能从中获益。

在Python编程中,装饰器(Decorator)是一种设计模式,它允许我们通过一种简洁、高效的方式来扩展或修改一个函数的行为。装饰器不仅仅是一种语法糖,它实际上是函数式编程的一个重要工具,通过高阶函数实现。本文将详细介绍装饰器的基本概念、常见用法以及一些高级技巧,帮助您在日常开发中更好地利用这一工具。

一、什么是装饰器?

1. 基本概念:

装饰器本质上是一个接受函数作为参数并返回一个新函数的高阶函数。它经常用于在不修改原函数代码的情况下,为函数添加新的功能。

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = original_function(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper_function

@decorator_function
def display():
    print("Display function ran")

display()

2. 输出结果:

Something is happening before the function is called.
Display function ran
Something is happening after the function is called.

3. 流程解析:

  • decorator_function 是一个装饰器函数,它接收一个函数 original_function 作为参数。
  • decorator_function 内部,定义了一个新的函数 wrapper_function,这个函数会在执行 original_function 前后进行一些操作。
  • @decorator_function 语法糖让 display 函数在调用时实际上是调用了 wrapper_function

二、常见的装饰器使用场景

1.日志记录:

在实际应用中,记录函数的执行信息是非常重要的。通过装饰器,我们可以在不修改原有函数的情况下添加日志功能。

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"{func.__name__} is called.")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished execution.")
        return result
    return wrapper

@log_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

2.性能计时:

测量函数的执行时间可以帮助我们找到性能瓶颈并进行优化。装饰器可以方便地实现这一功能。

import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} executed in {end_time - start_time} seconds")
        return result
    return wrapper

@timer_decorator
def slow_function():
    time.sleep(2)
    print("Slow function completed")

slow_function()

3.权限验证:

在Web应用中,权限验证是一个常见的需求。装饰器可以实现在不重复编写代码的情况下对多个视图函数进行权限控制。

def permission_required(permission):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if not current_user_has_permission(permission):
                raise PermissionError("Permission denied")
            return func(*args, **kwargs)
        return wrapper
    return decorator

def current_user_has_permission(permission):
    # Simulate a current user with specific permissions
    return True

@permission_required("admin")
def admin_only_function():
    print("Admin only function executed")

admin_only_function()

三、高级装饰器技巧

1.带参数的装饰器:

虽然装饰器通常只接受函数作为参数,但我们可以通过一些技巧使装饰器接受额外参数。

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

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

say_hello("Alice")

2.装饰器栈:

在一个函数上可以使用多个装饰器,这些装饰器会按照从下到上的顺序依次执行,形成一个装饰器栈。

def bold(func):
    def wrapper(*args, **kwargs):
        return f"<b>{func(*args, **kwargs)}</b>"
    return wrapper

def italic(func):
    def wrapper(*args, **kwargs):
        return f"<i>{func(*args, **kwargs)}</i>"
    return wrapper

@bold
@italic
def greet(name):
    return f"Hello, {name}!"

print(greet("Alice"))  # Output: <b><i>Hello, Alice!</i></b>

3.类装饰器和继承:

装饰器不仅可以用于函数,还可以用于类和方法。这在处理一些通用任务时非常有用,比如日志记录和事务管理。

def singleton(cls):
    instances = {
   }
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class MyClass:
    def __init__(self, value):
        self.value = value

obj1 = MyClass(10)
obj2 = MyClass(20)
print(obj1 is obj2)  # Output: True

四、总结

通过以上的介绍和示例,我们可以看到装饰器在Python中的强大之处。无论是简单的日志记录、性能测量,还是复杂的权限验证和参数处理,装饰器都能够提供简洁高效的解决方案。在实际开发中,合理利用装饰器不仅可以提高代码的可读性和可维护性,还能避免重复劳动,提升开发效率。希望这篇文章能够帮助您更好地理解和应用Python中的装饰器,为您的开发工作带来便利。

相关文章
|
25天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
2天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
279 12
|
17天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
5天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
20天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
22天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2583 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
4天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
175 2
|
2天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
5天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
273 2
|
21天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1580 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码