Python装饰器之类装饰器详解

2025-04-27 17:50
文章标签 装饰 python 详解

本文主要是介绍Python装饰器之类装饰器详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Python装饰器之类装饰器详解》本文将详细介绍Python中类装饰器的概念、使用方法以及应用场景,并通过一个综合详细的例子展示如何使用类装饰器,希望对大家有所帮助,如有错误或未考虑完全的地方,望不...

1. 引言

python中,装饰器是一种允许我们在不改变原有代码的情况下,动态地增加或修改函数和类功能的工具。

类装饰器相较于函数装饰器,功能更为强大和灵活,因为它们不仅可以修饰类的方法,还可以修饰类本身。

2. 装饰器的基本概念

装饰器是一个接受函数或类并返回一个新函数或新类的高阶函数。它们通常通过 @ 符号来使用。

在使用装饰器时,我们将装饰器放在被装饰对象的上方,这样装饰器就会在对象创建时自动应用。

2.1. 函数装饰器复习

在介绍类装饰器之前,我们先简单回顾一下函数装饰器的基本用法。

def my_decorator(func):
    def wrapper(*args, **kwargs):
        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):
    print(f"Hello, {name}!")

say_hello("Alice")

运行上述代码,输出结果为:

Something is happening before the function is called.
Hello, Alice!
Something is happening after the function is called.

2.2 类装饰器的定义和使用

类装饰器与函数装饰器类似,只不过它们接受一个类作为参数,并返回一个新类。

最简单的类装饰器可以这样定义:

def class_decorator(cls):
    class WrappedClass(cls):
        def new_method(self):
            print("This is a new method added by the decorator.")
        def existing_method(self)ktXkmwjaC:
            print("This method is overridden by the decorator.")
    return WrappedClass

@class_decorator
class MyClass:
    def existing_method(self):
        print("This method exists in the original class.")

obj = MyClass()
obj.new_method()          # 调用新增的方法
obj.existing_method()     # 调用被重写的方法

运行上述代码,输出结果为:

This is a new method added by the decorator.
This method is overridden by the decorator.

在这个例子中,class_decorator 是一个类装饰器,它接受一个类 MyClass 作为参数,并返回一个新的类 WrappedClassWrappedClass 继承自 MyClass,并新增和重写了一些方法。

3. 类装饰器的应用场景

类装饰器在实际开发中有很多应用场景,下面是几个常见的例子:

3.1. 自动添加属性

类装饰器可以用来自动为类添加一些属性。

例如,我们可以创建一个装饰器,自动为类添加一个 created_at 属性,记录对象的创建时间。

import datetime

def add_timestamp(cls):
    class WrappedClass(cls):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.created_at = datetime.datetime.now()
    return WrappedClass

@add_timestamp
class MyClass:
    def __init__(self, name):
        self.name = name

obj = MyClass("Alice")
print(obj.name)        # 输出: Alice
print(obj.created_at)  # 输出: 对象的创建时间

3.2 访问控制

类装饰器可以用来控制类的方法访问权限。

例如,我们可以创建一个装饰器,要求调用某些方法时必须有管理员权限javascript

def require_admin(cls):
    class WrappedClass(cls):
        def admin_method(self, *args, **kwargs):
            if not self.is_admin:
                raise PermissionError("Admin privileges required")
            return super().admin_method(*args, **kwargs)
    return WrappedClass

@require_admin
class MyClass:
 android   def __init__(self, is_admin):
        self.is_admin = is_admin

    def admin_method(self):
        print("This is an admin method.")

admin_obj = MyClass(is_admin=True)
admin_obj.admin_method()  # 正常调用

user_obj = MyClass(is_admin=False)
user_obj.admin_method()   # 抛出 PermissionError

3.3 数据验证

类装饰器可以用来在类方法调用前进行数据验证。

例如,我们可以创建一个装饰器,验证方法参数的类型。

def validate_params(cls):
    class WrappedClass(cls):
        def method_with_validation(self, x):
            if not isinstance(x, int):
                raise ValueError("Parameter x must be an integer")
            return super().method_with_validation(x)
    return WrappedClass

@validate_params
class MyClass:
    def method_with_validation(self, x):
        print(f"Received {x}")

obj = MyClass()
obj.method_with_validation(10)  # 正常调用
obj.method_with_validation("a") # 抛出 ValueError

4. 综合示例

接下来,我们将通过一个综合示例来展示如何使用类装饰器。

这个示例将包含一个日志记录装饰器、一个权限检查装饰器和一个数据验证装饰器。

import datetime

def log_activity(cls):
    class WrappedClass(cls):
        def __getattribute__(self, name):
            attr = super().__getattribute__(name)
            if callable(attr):
                def logged(*args, **kwargs):
                    print(f"Calling {name} with arguments {args} and {kwargs} at {datetime.datetime.now()}")
                    result = attr(*args, **kwargs)
                    print(f"{name} returned {result}")
                    return result
                return logged
            return attr
    return WrappedClass

def require_permission(permission):
    def decorator(cls):
        class WrappedClass(cls):
            def __getattribute__(self, name):
                attr = super().__getattribute__(name)
                if callable(attr):
                    def secured(*args, **kwargs):
                        if not self.has_permission(permission):
                            raise PermissionError(f"Permission {permission} required")
                        return attr(*args, **kwargs)
                    return secured
                return attr
        return WrappedClass
    return decorator

def validate_params(cls):
    class WrappedClass(cls):
        def method_with_validation(sChina编程elf, x):
            if not isinstance(x, int):
                raise ValueError("Parameter x must be an integer")
            return super().method_with_validation(x)
    return WrappedClass

@log_activity
@require_permission("admin")
@validate_params
class MyClass:
    def __init__(self, is_admin):
     android   self.is_admin = is_admin

    def has_permission(self, permission):
        return self.is_admin

    def method_with_validation(self, x):
        return f"Received {x}"

# 测试综合示例
admin_obj = MyClass(is_admin=True)
print(admin_obj.method_with_validation(10))  # 正常调用

try:
    admin_obj.method_with_validation("a")  # 抛出 ValueError
except ValueError as e:
    print(e)

user_obj = MyClass(is_admin=False)
try:
    user_obj.method_with_validation(10)  # 抛出 PermissionError
except PermissionError as e:
    print(e)

4.1 输出结果

Calling __init__ with arguments (True,) and {} at 2024-07-11 14:23:45.123456
__init__ returned None
Calling method_with_validation with arguments (10,) and {} at 2024-07-11 14:23:45.123456
method_with_validation returned Received 10
Received 10
Calling method_with_validation with arguments ('a',) and {} at 2024-07-11 14:23:45.123456
Parameter x must be an integer
Calling __init__ with arguments (False,) and {} at 2024-07-11 14:23:45.123456
__init__ returned None
Calling method_with_validation with arguments (10,) and {} at 2024-07-11 14:23:45.123456
Permission admin required

4.2 解释

  1. 日志记录装饰器:记录类的方法调用,包括输入参数和返回值。
  2. 权限检查装饰器:检查用户是否具有调用方法的权限。
  3. 数据验证装饰器:验证方法参数的类型。

通过这种方式,我们可以在不修改类本身的情况下,为类添加额外的功能。

总结

类装饰器是 Python 中一个非常强大的工具,可以用来扩展和修改类的行为。通过类装饰器,我们可以在不修改原始代码的情况下为类添加额外的功能。

在实际开发中,类装饰器有很多应用场景,包括日志记录、访问控制、数据验证等。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于Python装饰器之类装饰器详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154398

相关文章

使用Python实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.

Python 交互式可视化的利器Bokeh的使用

《Python交互式可视化的利器Bokeh的使用》Bokeh是一个专注于Web端交互式数据可视化的Python库,本文主要介绍了Python交互式可视化的利器Bokeh的使用,具有一定的参考价值,感... 目录1. Bokeh 简介1.1 为什么选择 Bokeh1.2 安装与环境配置2. Bokeh 基础2

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

Python ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-