【Python知识】Python进阶-什么是装饰器?

Python装饰器介绍

    • 概述
      • [1. 基本装饰器](#1. 基本装饰器)
      • [2. 带参数的装饰器](#2. 带参数的装饰器)
      • [3. 带参数的函数装饰器(使用`functools.wraps`)](#3. 带参数的函数装饰器(使用functools.wraps))
      • [4. 类装饰器](#4. 类装饰器)
      • [5. 方法装饰器(在类中使用)](#5. 方法装饰器(在类中使用))
    • 参考文献

概述

Python装饰器是一种高级功能,允许你在不修改函数或方法定义的情况下,为其添加额外的功能或行为。装饰器本质上是一个高阶函数,它接受一个函数作为参数,并返回一个新的函数(或可调用对象)。下面是一些常见的Python装饰器类型,以及每个类型的具体例子:

1. 基本装饰器

基本装饰器是最简单的装饰器类型,它可以在函数调用前后添加一些额外的逻辑。

python 复制代码
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

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

say_hello()

输出:

复制代码
Something is happening before the function is called.
Hello!
Something is happening after the function is called.

2. 带参数的装饰器

装饰器也可以接受参数,这允许你创建更灵活的装饰器。

python 复制代码
def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat

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

greet("Alice")

输出:

复制代码
Hello, Alice!
Hello, Alice!
Hello, Alice!

3. 带参数的函数装饰器(使用functools.wraps

为了保持被装饰函数的元数据(如函数名、文档字符串等),可以使用functools.wraps装饰器。

python 复制代码
import functools

def debug(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f"{func.__name__}({args!r}, {kwargs!r}) = {result!r}")
        return result
    return wrapper

@debug
def add(a, b):
    return a + b

print(add(2, 3))

输出:

复制代码
add((2, 3), {}) = 5
5

4. 类装饰器

类装饰器与函数装饰器类似,但它们应用于类而不是函数。

python 复制代码
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.value)  # 输出: 10
print(obj2.value)  # 输出: 10,因为obj1和obj2是同一个实例

5. 方法装饰器(在类中使用)

虽然方法本质上也是函数,但直接在类中为方法定义装饰器需要稍微不同的语法。

python 复制代码
def method_decorator(func):
    def wrapper(self, *args, **kwargs):
        print("Method is being called")
        return func(self, *args, **kwargs)
    return wrapper

class MyClass:
    @method_decorator
    def my_method(self):
        print("Inside my_method")

obj = MyClass()
obj.my_method()

输出:

复制代码
Method is being called
Inside my_method

请注意,对于类中的方法,装饰器通常还需要接受self(或cls对于类方法)作为第一个参数。

这些例子展示了装饰器在Python中的多种用途。装饰器是Python中一个非常强大且灵活的工具,可以用来实现各种设计模式、日志记录、性能测量、事务管理等功能。

参考文献

【Python知识】Python面向对象编程知识

相关推荐
fouryears_234172 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~2 小时前
C#---StopWatch类
开发语言·c#
lifallen4 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研4 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
mit6.8245 小时前
[1Prompt1Story] 滑动窗口机制 | 图像生成管线 | VAE变分自编码器 | UNet去噪神经网络
人工智能·python
没有bug.的程序员5 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋5 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
cui__OaO5 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习
鱼鱼说测试6 小时前
Jenkins+Python自动化持续集成详细教程
开发语言·servlet·php