Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Decorator -- staticmethod / classmethod / property 的超强对比表

🚀 Python 三大方法类型:终极对比表

特性 普通方法 @staticmethod @classmethod @property
自动注入参数 self(实例) 无自动参数 cls(类) self(实例)
能否访问实例属性
能否访问类属性
是否依赖实例 ✅ 强依赖 ❌ 完全不依赖 ❌ 不依赖实例 ✅ 获取实例状态
调用方式 实例调用 类 / 实例均可 类 / 实例均可 实例属性访问方式
典型用途 操作实例数据 工具函数、转换函数 工厂方法、配置、类级别操作 将方法伪装成“属性”
是否支持 setter ✅ 可做属性可写化
是否支持继承多态 ✅(但少用) ✅(常见,用于子类构造)
设计意图 行为依赖对象状态 与类逻辑相关但不依赖类/实例 以“类”为核心逻辑 将 getter 方法包装成字段

终极记忆口诀

  • self -> 普通方法
  • cls -> classmethod
  • nothing -> staticmethod
  • 属性接口 -> property

📌 三者核心差异一句话概括

@staticmethod

完全与实例无关,只是被“放在类里面的工具函数”。

@classmethod

方法围绕“类”本身展开,通常用于创建对象、加载配置、适配子类。

@property

把方法变成字段一样访问,实现干净优雅的 API。

📘 实用示例对比(项目级示例)

1. staticmethod — 逻辑函数 / 工具函数

用于转换、校验、格式化等逻辑。

class Math:
    @staticmethod
    def add(a, b):
        return a + b

使用:

Math.add(1, 2)

不需要类,也不需要实例。

2. classmethod — 工厂方法 / 适配子类

例如从 JSON 创建对象:

class User:
    def __init__(self, name):
        self.name = name

    @classmethod
    def from_dict(cls, data):
        return cls(data["name"])

支持子类:

class Admin(User):
    pass

a = Admin.from_dict({"name": "root"})
print(type(a))  # <class '__main__.Admin'>

3. property — 优雅访问对象属性

class User:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    @property
    def fullname(self):
        return f"{self.firstname} {self.lastname}"

像字段一样访问:

print(user.fullname)

而不是:

print(user.fullname())

📦 更高级示例:统一对比(一个类里展示全部)

class Demo:
    class_level_value = 100

    def __init__(self, x):
        self.x = x

    def normal(self):
        return self.x * 2

    @staticmethod
    def util(a, b):
        return a + b

    @classmethod
    def make(cls, y):
        return cls(y)

    @property
    def doubled(self):
        return self.x * 2

调用:

d = Demo(10)

d.normal()       # 20
Demo.util(1, 2)  # 3
Demo.make(99)    # 创建 Demo 或其子类对象
d.doubled        # 20(注意:没有括号)

🏆 什么时候用哪一个?(超明确场景指导)

| 场景 | 用什么 | 原因 | | 方法逻辑与实例有关 | 普通方法 | 需要 self | | 工具函数、数据转换、格式化 | staticmethod | 独立逻辑、放类里更组织化 | | 基于类创建对象(工厂) | classmethod | 返回 cls,可兼容子类 | | 加载配置/初始化环境 | classmethod | 逻辑属于类本身 | | 将 getter “伪装成属性” | property | 让 API 更优雅 | | 需要可写属性 | @property + @setter | 控制写入逻辑 | | 完全无关类、应该放 utils | 顶级函数或 staticmethod | 避免污染类职责 |

🎁 最后附赠:你的项目最佳结构建议

你 FastAPI + PostgreSQL 项目建议这样:

utils/
  ├── string.py
  ├── validate.py
  ├── date.py
  ├── stock.py
  ├── crypto.py

类里面使用组合:

  • 逻辑独立 -> @staticmethod
  • 可能支持子类扩展 -> @classmethod
  • 数据对象计算属性 -> @property

这样你的 utils 模块会非常清晰。