← [ BACK_TO_NOTES ]

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

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

#concept #growing #dev #python #python

[!info] related notes

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

这个概念为什么出现

同一段逻辑有时需要:

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

这三种绑定方式把意图说清楚;普通实例方法不需要装饰器。

[!abstract] 一句话理解 实例方法收 self,@classmethod 收 cls,@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:
        sign = "-" if amount_cents < 0 else ""
        whole, cents = divmod(abs(amount_cents), 100)
        return f"{sign}{whole}.{cents:02d}"


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_payload 用 cls 构造调用它的类,前提是子类构造签名兼容。本例仅演示绑定:int(...) 会转换/截断某些输入,不是完整支付数据校验。
  2. format_money 不依赖状态:静态方法避免假装需要 self。
  3. 金额格式化用整数拆分,避免大额整数转 float 丢精度;此工具也能写成模块级函数。

核心概念与准确模型

类型装饰器自动传入典型用途
实例方法无经实例访问时绑定实例;经类访问须显式传入行为
类方法@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/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本