• 【python】(七)python内置装饰器: @classmethod和@staticmethod



    1. 内置类装饰器

    1.1 类装饰器

    内置装饰器含义
    classmethod类方法
    staticmethod静态方法

    内置装饰器优点:

    1. 不需要实例化,可以直接调用
    2. 提升代码的可读性

    1.2 普通方法

    • 定义:
      • 第一个参数为self,代表 实例本身
    • 调用:
      • 要有实例化的过程,通过 实例对象.方法名 调用
    # 1. 定义
    class MethodsDemo:
        param_a = 0 #类变量
        def normal_demo(self): # 定义一个类方法,第一个参数必须为self
            """
            普通方法
            :return:
            """
            print("这是一个普通方法", self.param_a)
    # 2. 调用
    md = MethodsDemo()  #先实例化
    md.normal_demo()  #通过示例对象去调用方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.3 类方法

    • 定义:
      • 使用 @classmethod 装饰器,第一个参数为类本身,所以通常使用cls命名做区分(非强制)
      • 在类内可以直接使用类方法或类变量,无法直接使用实例变量或方法
    • 调用:
      • 无需实例化,直接通过 类.方法名 调用,也可以通过实例.方法名调用
    • 注意:
      • 类方法内不可以直接调用实例方法,也不可以调用实例变量
      • 类和实例都可以直接调用类方法。
    • 使用环境:在不修改原有代码的基础上,进行二次功能拓展。
    # 1. 类的定义
    class MethodsDemo:
        param_a = 0
        # 定义类方法必须加 classmethod装饰器
        @classmethod
        def classmethod_demo(cls):
            """
            类方法,第一个参数需要改为cls
            :return:
            """
            print("类方法", cls.param_a)
    
    # 2. 类的调用
    MethodsDemo.classmethod_demo() # 无需实例化,直接调用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.4 静态方法

    • 定义:
      • 使用 @staticmethod 装饰器,没有和类本身有关的参数
      • 无法直接使用任何类变量、类方法或者实例方法、实例变量
    • 调用:
      • 无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
    # 1. 定义
    class MethodsDemo:
        param_a = 0
        @staticmethod
        def static_demo():
            """
            静态方法
            :return:
            """
            print("静态方法") # 无法直接调用类变量
    # 2. 调用
    MethodsDemo.static_demo()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.5 总结

    名称定义调用关键字使用场景
    普通方法至少需要一个参数self实例名.方法名()方法内部涉及到实例对象属性的操作
    类方法至少需要一个cls参数类名.方法名()或者实例名.方法名()@classmethod如果需要对类属性,即静态变量进行限制性操作
    静态方法无默认参数类名.方法名()或者实例名.方法名()@staticmethod无需类或实例参与

    2. 类方法实际案例

    • 代码实现的需求是格式化输出时间
    • 如果现在需求变更,输入 年、月、日 没法保证格式统一,可能是json,可能是其他格式的字符串,在不修改构造函数的前提下,如何更改代码
    class DateFormat:
        def __init__(self, year=0, month=0, day=0):
            self.year = year
            self.month = month
            self.day = day
    
        def out_date(self):
            return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"
    
        @classmethod
        def json_format(cls,json_data):
            """
            输入字典格式日期信息
            :param json_data:
            :return: tuple
            """
            year,month,day=json_data["year"],json_data["month"],json_data["day"]
            #相当于return DateFormat(),相当于返回一个类的示例对象
            return cls(year,month,day)
    
    #json格式的日期
    json_data={"year":2022,"month":8,"day":30}
    
    #使用接送格式化生成想要的日期格式,返回Dateformat实例
    demo = DateFormat.json_format(json_data)
    print(demo.out_date())  
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3. 静态方法实际案例

    • 此方法没有任何和实例、类相关的部分,可以作为一个独立函数使用
    • 某些场景下,从业务逻辑来说又属于类的一部分
    • 例子:简单工厂方法
    # static 使用场景
    class HeroFactory:
        # staticmethod 使用场景,
        # 方法所有涉及到的逻辑都没有使用实例方法或者实例变量的时候
        # 伪代码
        @staticmethod
        def create_hero(hero):
            if hero == "ez":
                return EZ()
            elif hero == "jinx":
                return Jinx()
            elif hero == "timo":
                return Timo()
            else:
                raise Exception("此英雄不在英雄工厂当中")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    从零学习开发一个RISC-V操作系统(一)丨计算机组成原理相关知识与RISC-V指令集简介
    【递归、搜索与回溯算法】第三节.21. 合并两个有序链表和206. 反转链表和24. 两两交换链表中的节点
    前端项目如何准确预估个人工时
    【Datawhale学习笔记】从大模型到AgentScope
    Jenkinsfile 同时检出多个 Git 仓库
    [SDR] GNU Radio 系列教程(二) —— 绘制第一个信号分析流程图
    视听杂志视听杂志社视听编辑部2022年第11期目录
    YOLO目标检测——路标数据集+已标注voc和yolo格式标签下载分享
    springcloud13:服务网关(gateway)
    【Java8新特性】- Lambda表达式
  • 原文地址:https://blog.csdn.net/gjj920318/article/details/126834858