在 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!"@classmethoddef 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 = titleself.author = author@classmethoddef 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:@staticmethoddef add(x, y):return x + yprint(MyMath.add(3, 5)) # ? 8
特點:
-
不接收
self
或cls
參數 -
和普通函數類似,但歸屬在類中,邏輯上與類相關
-
常用于:
- 與類操作相關的工具方法
- 不需要訪問類或實例內部狀態
示例:靜態方法作為工具函數
class Temperature:def __init__(self, celsius):self.celsius = celsius@staticmethoddef to_fahrenheit(c):return c * 9 / 5 + 32def 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@classmethoddef create_dog(cls):return cls("Dog")@classmethoddef 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 = {}@classmethoddef register(cls, name, creator):cls._creators[name] = creator@classmethoddef 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 = radiusclass 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@classmethoddef 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 = Nonedef __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:@staticmethoddef add(x, y):return x + y@staticmethoddef multiply(x, y):return x * yprint(MathUtils.add(3, 4)) # ? 7
print(MathUtils.multiply(3, 4)) # ? 12
4、小結
設計模式 | 推薦使用 | 原因 |
---|---|---|
工廠模式 | @classmethod | 需要訪問類構造器、支持多種創建方式 |
單例模式 | @classmethod / __new__ | 控制實例生成的唯一性 |
工具類 | @staticmethod | 無需訪問類/實例,僅提供輔助功能 |