在 Python 中,类方法 (@classmethod
) 和静态方法 (@staticmethod
) 是类作用域下的两种特殊方法。它们使用装饰器定义,并且与实例方法 (def func(self)
) 的行为有所不同。
1. 三种方法的对比概览
方法类型 | 是否访问实例 (self ) |
是否访问类 (cls ) |
典型用途 |
---|---|---|---|
实例方法 | ✅ 是 | ❌ 否 | 访问对象属性 |
类方法 @classmethod |
❌ 否 | ✅ 是 | 创建类的替代构造器,访问类变量等 |
静态方法 @staticmethod |
❌ 否 | ❌ 否 | 工具函数,与类逻辑相关但不依赖类或实例 |
2. 实例方法(默认方法)
class MyClass:
def instance_method(self):
print(f"This is an instance method. self = {self}")
obj = MyClass()
obj.instance_method() # 输出 self 为该实例
3. 类方法 @classmethod
class MyClass:
class_var = "Hello, Class!"
@classmethod
def class_method(cls):
print(f"This is a class method. cls = {cls}")
print(f"Access class_var = {cls.class_var}")
MyClass.class_method() # 通过类调用
obj = MyClass()
obj.class_method() # 通过实例也可以调用
🔹 特点:
第一个参数是
cls
,代表类本身常用于:
- 构造不同初始化方式
- 修改/访问类变量
- 工厂模式 (
from_*
等)
示例:类方法作为工厂方法
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
@classmethod
def from_string(cls, book_str):
title, author = book_str.split(",")
return cls(title.strip(), author.strip())
book = Book.from_string("1984, George Orwell")
print(book.title) # ➜ 1984
4. 静态方法 @staticmethod
class MyMath:
@staticmethod
def add(x, y):
return x + y
print(MyMath.add(3, 5)) # ➜ 8
特点:
不接收
self
或cls
参数和普通函数类似,但归属在类中,逻辑上与类相关
常用于:
- 与类操作相关的工具方法
- 不需要访问类或实例内部状态
示例:静态方法作为工具函数
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
@staticmethod
def to_fahrenheit(c):
return c * 9 / 5 + 32
def show(self):
print(f"{self.celsius}°C = {self.to_fahrenheit(self.celsius)}°F")
temp = Temperature(25)
temp.show() # ➜ 25°C = 77.0°F
总结:何时用哪种方法?
场景 | 推荐方法 |
---|---|
需要访问或修改实例属性 | 实例方法 |
需要访问或修改类变量、类构造 | 类方法 @classmethod |
工具函数:与类相关但不访问类或实例成员 | 静态方法 @staticmethod |
@classmethod
和 @staticmethod
应用场景实战
利用 Python 中的 @classmethod
和 @staticmethod
可以优雅地实现设计模式,如单例模式和工厂模式。下面我将分别讲解这两种模式的原理、适用场景,并结合代码示例说明如何使用类方法或静态方法实现。
1、工厂模式(Factory Pattern)
定义:工厂模式是一种创建对象的设计模式,它允许类在创建对象时不暴露实例化逻辑,而是通过类方法返回不同的类实例。
使用类方法实现工厂模式
class Animal:
def __init__(self, name):
self.name = name
@classmethod
def create_dog(cls):
return cls("Dog")
@classmethod
def create_cat(cls):
return cls("Cat")
# 使用工厂方法创建对象
dog = Animal.create_dog()
cat = Animal.create_cat()
print(dog.name) # ➜ Dog
print(cat.name) # ➜ Cat
应用场景
- 多种初始化方式(如从字符串、文件、数据库等)
- 根据条件返回不同子类对象
更复杂示例:带注册机制的工厂
class ShapeFactory:
_creators = {}
@classmethod
def register(cls, name, creator):
cls._creators[name] = creator
@classmethod
def create(cls, name, *args, **kwargs):
if name not in cls._creators:
raise ValueError(f"Unknown shape: {name}")
return cls._creators[name](*args, **kwargs)
# 各种 Shape 类
class Circle:
def __init__(self, radius):
self.radius = radius
class Square:
def __init__(self, length):
self.length = length
# 注册
ShapeFactory.register("circle", Circle)
ShapeFactory.register("square", Square)
# 创建对象
c = ShapeFactory.create("circle", 5)
s = ShapeFactory.create("square", 3)
print(c.radius) # ➜ 5
print(s.length) # ➜ 3
2、单例模式(Singleton Pattern)
定义:单例模式保证类在程序中只有一个实例。
使用类方法实现单例
class Singleton:
_instance = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
# 测试
a = Singleton.get_instance()
b = Singleton.get_instance()
print(a is b) # ➜ True
也可以结合 __new__
实现单例
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
# 所有实例是同一个
a = Singleton()
b = Singleton()
print(a is b) # ➜ True
3、静态方法在设计模式中的作用
工具类模式(Utility Pattern)
静态方法常用于实现工具类(即所有方法都与对象状态无关,仅执行逻辑计算)。
class MathUtils:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
print(MathUtils.add(3, 4)) # ➜ 7
print(MathUtils.multiply(3, 4)) # ➜ 12
4、小结
设计模式 | 推荐使用 | 原因 |
---|---|---|
工厂模式 | @classmethod |
需要访问类构造器、支持多种创建方式 |
单例模式 | @classmethod / __new__ |
控制实例生成的唯一性 |
工具类 | @staticmethod |
无需访问类/实例,仅提供辅助功能 |