python中各种装饰器的作用
classmethod 和 staticmethod 的区别
参考文章链接
语法区别
- @classmethod 的第一个参数为类本身(cls),正如实例方法的第一个参数为对象本身(self)
- @staticmethod 的第一个参数不需要传入 cls 或 self,故 staticmethod 中是无法访问类和对象的数据的
调用时
- 都可用类名直接调用
- 也可用实例对象调用(不推荐,没必要)
使用场景
- classmethod 可以设置修改了属性,也可以实例化对象;
- staticmethod 无法访问类或者对象的数据,所以可以把他当做一个辅助功能方法用,里面博涵一些与该类有关的逻辑代码
案例 1
需求:从本地文件中(txt, csv, json等等)读取数据,生成一个对象。比如,本地有一个data.json文件,里面包含了每个学生的姓名及对应的考试成绩。现在要求读取该数据,生成一个class对象。
思路:
__init__方法中,清晰的声明对象的属性
用一个classmethod:load_json,专门用于读取data_file,获取数据,实例化对象
用一个staticmethod:validate,来对要初始化数据进行有效性检查
class Class:def __init__(self, names, grades):self._names = namesself._grades = grades@classmethoddef load_json(cls, data_file):# 读取数据,获得names,gradescls.validate(names,grades)return cls(names, grades)@staticmethoddef validate(names, grades):# 检查数据有效性pass
个人理解:
@staticmethod 是一个类方法,他具有改变类状态的能力,可以更改所有实例的变量。
它具有如下作用:
- 创建实例
- 类方法可以用来创建类的新实例,特别是当创建过程需要一些额外的逻辑时。
- 这种方法有时被称为工厂方法,因为它们可以替代构造函数来创建对象。
class Person:def __init__(self, name, age):self.name = nameself.age = age@classmethoddef from_birth_year(cls, name, birth_year):# 假设当前年份为2024age = 2024 - birth_yearreturn cls(name, age)# 使用工厂方法创建Person实例
p = Person.from_birth_year("Alice", 1990)
print(p.age) # 输出: 34
- 访问和修改类属性
- 类方法可以直接访问和修改类的属性,而不必通过实例。
- 这对于维护类的状态非常有用。
class Counter:count = 0@classmethoddef increment(cls):cls.count += 1@classmethoddef get_count(cls):return cls.count# 使用类方法
Counter.increment()
Counter.increment()
print(Counter.get_count()) # 输出: 2
- 作为工具方法:
- 类方法可以用作与类相关的工具方法,这些方法可能不是直接用于创建实例,而是提供了一些辅助功能。
class MathUtils:@classmethoddef gcd(cls, a, b):while b != 0:a, b = b, a % breturn a# 使用工具方法
print(MathUtils.gcd(18, 24)) # 输出: 6
- 提高代码的清晰度:
- 使用类方法可以让代码更加清晰易懂,特别是在需要创建复杂的实例或者执行与类相关操作的情况下。
- 避免重复创建实例:
- 类方法可以用来检查是否已经存在某个实例,从而避免重复创建相同实例。
class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls, *args, **kwargs)return cls._instance@classmethoddef get_instance(cls):return cls()s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2) # 输出: True