飞酷告诉你@classmethod类方法的作用原来那么大
2024-06-12 加入收藏
大家好,我是小K,今天由我来为大家讲解类方法和类方法的使用场景。
什么是类方法?
要说什么是类方法,就肯定要先说下什么是类,什么是方法。(废话)
类
用来描述具有相同的属性和方法的对象的集合。
它定义了该集合中每个对象所共有的属性和方法。
对象是类的实例。
方法
类中定义的函数。
这里方法是指所有定义在类里面的方法,包含实例方法、静态方法、类方法。
但我们今天所说的类方法并不是类+方法,而是类里面方法的一种。
类方法
修饰器@classmethod
来标识其为类方法,第一个参数必须要默认传类,一般习惯用cls
(表示类本身)。
类方法是只与类本身有关而与实例无关的方法。
通过cls
引用的必定是类对象的属性和方法,不能访问实例属性,能够通过实例对象和类对象去访问类方法。
代码示例:
class MyClass:
counter = 0 # 类属性
@classmethod
def increment(cls):
cls.counter += 1
# 调用类方法
MyClass.increment()
print(MyClass.counter) # 输出 1
上述代码中我们不需要实例化MyClass
就可执行类中的increment
函数,还可以拿到/修改类属性的值。
所以这对于管理类级别的状态是非常有用的。
类方法的用处
1. 工厂方法
类方法可以用作工厂函数,创建类的实例并返回。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def create_person(cls, name, birth_year):
age = datetime.now().year - birth_year
return cls(name, age)
# 使用类方法创建实例
person = Person.create_person("John", 1990)
用当前年份减去出生年份来计算年龄(age),然后使用这些信息创建并返回一个新的Person类实例。
2. 提供备用构造函数
类方法允许提供不同的构造方式,以满足不同的需求。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def from_tuple(cls, point_tuple):
return cls(*point_tuple)
# 使用类方法创建实例
point = Point.from_tuple((3, 4))
3. 多线程锁
在多线程环境中,类方法可以与锁一起使用,确保对共享资源的访问是线程安全的,防止竞争条件和数据不一致
import threading
class Counter:
count = 0
lock = threading.Lock()
@classmethod
def increment(cls):
with cls.lock:
cls.count += 1
# 在多线程环境中安全地增加计数
def worker():
for _ in range(100000):
Counter.increment()
# 创建多个线程来执行工作
threads = [threading.Thread(target=worker) for _ in range(5)]
# 启动线程
for thread in threads:
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
# 输出最终的计数值
print(Counter.count)
只有用类方法拿到锁,才允许进行
count += 1
的操作。
最后
相比实例方法,类方法是一个很容易被忽略的知识点,很多入门书里并不会以此为重点去讲解它的用途和特点。
但在一些处理与整个类相关的任务,使用类方法还是一个非常明智的选择。