Python 实例方法、类方法与静态方法

实例方法绑定 self,classmethod 绑定 cls,staticmethod 无自动绑定;用于工厂、备选构造与无状态工具函数。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 实例方法、类方法与静态方法

这个概念为什么出现

同一段逻辑有时需要:

  • 操作某个实例
  • 操作类本身(备选构造)
  • 只是挂在类命名空间下的函数

三种装饰器把意图说清楚。

[!abstract] 一句话理解 实例方法收 self@classmethodcls@staticmethod 无自动参数;类方法常用于工厂,静态方法是命名空间化的函数。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:订单既可常规创建,也可从支付回调字典构建

# order_methods_demo.py
# 业务意图:常规构造 + from_payload 工厂 + 金额格式化工具。
# 教学点:
# - 实例方法;
# - classmethod 工厂;
# - staticmethod 无状态工具。

from __future__ import annotations


class Order:
    def __init__(self, order_id: str, amount_cents: int) -> None:
        self.order_id = order_id
        self.amount_cents = amount_cents

    def label(self) -> str:
        return f"{self.order_id}:{self.format_money(self.amount_cents)}"

    @classmethod
    def from_payload(cls, payload: dict) -> Order:
        # 业务:支付回调 JSON -> Order;用 cls 以支持子类。
        return cls(payload["id"], int(payload["amount_cents"]))

    @staticmethod
    def format_money(amount_cents: int) -> str:
        return f"{amount_cents/100:.2f}"


def main() -> None:
    o1 = Order("O-1", 1999)
    o2 = Order.from_payload({"id": "O-2", "amount_cents": 500})
    print(o1.label())
    print(o2.label())
    print(Order.format_money(50))


if __name__ == "__main__":
    main()

建议运行:

python order_methods_demo.py

期望输出:

O-1:19.99
O-2:5.00
0.50

结合场景再看三个关注点

  1. from_payloadcls:子类继承工厂时仍构造子类。
  2. format_money 不依赖状态:静态方法避免假装需要 self。
  3. 也能写成模块级函数;放类上是为了发现性。

核心概念与准确模型

类型装饰器自动传入典型用途
实例方法实例行为
类方法@classmethod工厂/备选构造
静态方法@staticmethod工具函数

边界情况与反直觉行为

  1. 经实例调用 classmethod 仍传入类对象。
  2. 静态方法可被无意义覆盖成需要 self 的逻辑——失去清晰性。
  3. 抽象基类工厂常与 classmethod 组合。

常见误区

[!warning] 常见误区:能写 staticmethod 的都该写 错误理解:少一个 self 更干净。
正确模型:与类概念强相关才挂上去;否则模块函数更简单。

工程实践

  • 多构造路径:classmethod
  • 纯转换:优先模块函数或 staticmethod
  • 测试工厂与实例方法分开测

本节总结

三种方法是绑定约定,用来表达意图,不是语法炫技。

自测题

  1. 为什么工厂推荐 classmethod 而不是 staticmethod?
  2. 实例方法的第一个参数一定叫 self 吗?
参考答案
  1. cls 保留继承多态,子类调用得到子类实例。
  2. 名字是约定,绑定的是第一个位置参数。

延伸阅读与资料来源

资料类型支撑内容
classmethod文档内置装饰器
staticmethod文档内置装饰器
创建于 2026/5/20 更新于 2026/7/15