Day 31 类的装饰器

类装饰器本质上是一个可调用对象(通常是函数),它接收被装饰的类作为参数,对这个类进行修改(比如添加属性、方法,或修改现有行为),最后返回修改后的类(或一个新类)。

1.简单示例(无参数):

python 复制代码
# 定义类装饰器:为类添加日志功能
def class_logger(cls):
    # 保存原始的 __init__ 方法
    original_init = cls.__init__

    def new_init(self, *args, **kwargs):
        # 新增实例化日志
        print(f"[LOG] 实例化对象: {cls.__name__}")
        original_init(self, *args, **kwargs)  # 调用原始构造方法

    # 将类的 __init__ 方法替换为新方法
    cls.__init__ = new_init

    # 为类添加一个日志方法(示例)
    def log_message(self, message):
        print(f"[LOG] {message}")

    cls.log = log_message  # 将方法绑定到类,这是一种将外部函数添加为类的属性的方法
    return cls


# 定义简单打印类,应用装饰器
# 同样是语法糖的写法
@class_logger
class SimplePrinter:
    def __init__(self, name):
        self.name = name  # 构造方法:初始化名称

    def print_text(self, text):
        """简单打印方法"""
        print(f"{self.name}: {text}")


# 使用示例
printer = SimplePrinter("Alice")  # 实例化时触发装饰器的日志
printer.print_text("Hello, World!")  # 调用普通方法
printer.log("这是装饰器添加的日志方法")  # 调用装饰器新增的方法

2.带参数的装饰器:

如果需要给类装饰器传递参数,需要多一层嵌套函数:

python 复制代码
# 带参数的类装饰器:自定义添加的属性值
def add_custom_info(author, version):
    # 外层函数接收装饰器参数
    def decorator(cls):
        # 内层函数接收被装饰的类
        cls.author = author
        cls.version = version
        
        def show_info(self):
            print(f"类名:{self.__class__.__name__}")
            print(f"作者:{cls.author},版本:{cls.version}")
        
        cls.show_info = show_info
        return cls
    return decorator

# 使用带参数的装饰器
@add_custom_info(author="你", version="2.0")
class MyClass2:
    def __init__(self, name):
        self.name = name

# 测试
obj2 = MyClass2("带参数的类")
print(obj2.version)  # 输出:2.0
obj2.show_info()
# 输出:
# 类名:MyClass2
# 作者:你,版本:2.0

其中,self.__class__.__name__ 的作用就是:在类的实例方法中,获取当前对象所属类的名称(字符串)。其与type(self).__name__和类名.__name__作用一致,优势是动态性,能适配继承场景。

python 复制代码
class User:
    def show_fixed_name(self):
        # 固定指向User类,即使子类调用也不会变
        print(f"固定类名:{User.__name__}")
    
    def show_dynamic_name(self):
        # 动态指向实例实际所属的类
        print(f"动态类名:{self.__class__.__name__}")

class Admin(User):
    pass

admin = Admin()
admin.show_fixed_name()    # 输出:固定类名:User
admin.show_dynamic_name()  # 输出:动态类名:Admin

3.也可用类定义装饰器

python 复制代码
class ClassDecorator:
    def __init__(self, author="默认作者"):
        # 接收装饰器参数
        self.author = author
    
    def __call__(self, cls):
        # __call__方法接收被装饰的类
        cls.author = self.author
        
        def show_author(self):
            print(f"当前类作者:{self.author}")
        
        cls.show_author = show_author
        return cls

# 使用类装饰器(无参数)
@ClassDecorator()
class MyClass3:
    pass

# 使用类装饰器(有参数)
@ClassDecorator(author="你自定义的作者")
class MyClass4:
    pass

# 测试
obj3 = MyClass3()
obj3.show_author()  # 输出:当前类作者:默认作者

obj4 = MyClass4()
obj4.show_author()  # 输出:当前类作者:你自定义的作者

@浙大疏锦行

相关推荐
木风小助理9 小时前
`mapfile`命令详解:Bash中高效的文本至数组转换工具
开发语言·chrome·bash
彼岸花开了吗9 小时前
构建AI智能体:八十、SVD知识整理与降维:从数据混沌到语义秩序的智能转换
人工智能·python·llm
yyy(十一月限定版)9 小时前
初始matlab
开发语言·matlab
LawrenceLan9 小时前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
listhi5209 小时前
基于MATLAB的支持向量机(SVM)医学图像分割方法
开发语言·matlab
hui函数10 小时前
如何解决 pip install 编译报错 g++: command not found(缺少 C++ 编译器)问题
开发语言·c++·pip
山土成旧客10 小时前
【Python学习打卡-Day40】从“能跑就行”到“工程标准”:PyTorch训练与测试的规范化写法
pytorch·python·学习
Tisfy10 小时前
网站访问耗时优化 - 从数十秒到几百毫秒的“零成本”优化过程
服务器·开发语言·性能优化·php·网站·建站
济61710 小时前
嵌入式C语言(第一期)
c语言·开发语言
闲人编程10 小时前
消息通知系统实现:构建高可用、可扩展的企业级通知服务
java·服务器·网络·python·消息队列·异步处理·分发器