只要在类中实现__format__方法,就能自定义format()、f-string和str.format()的输出,其第一个参数是冒号后的格式说明符(如'iso'或'.2f'),需手动解析并处理。

直接说结论:只要在类里实现 __format__ 方法,就能让 format()、f-string 和 str.format() 按你想要的方式输出对象——但它的参数不是格式字符串本身,而是你传给 format() 的那个“格式说明符”(比如 '08x' 或 'short'),这点最容易搞错。
为什么 __format__ 的第一个参数是 format_spec 而不是整个格式表达式?
Python 调用 __format__ 时,会把 format(obj, spec) 中的 spec(即花括号里冒号后面的部分)原样传进来。它不解析、不预处理,也不告诉你用了哪种格式化方式(比如是不是 f-string)。所以你得自己约定并解析这个字符串。
-
format(my_date, 'iso')→__format__(self, 'iso') -
f"{my_point:.2f}"→__format__(self, '.2f') -
"{!r}".format(obj)不会调用__format__,走的是__repr__
怎么设计 format_spec 才不容易翻车?
别试图兼容所有内置格式语法(比如 '.2f' 对日期毫无意义),优先支持语义化标识符。如果真要兼容数字类格式,务必先检查类型,再委托给内置类型处理,否则容易抛 ValueError。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 推荐用短关键词:
'full'、'brief'、'debug',清晰且无歧义 - 若需支持数字精度,先判断
format_spec是否匹配r'^\.\d+f$'这类模式,再转给float(...).__format__(format_spec) - 空字符串
''是默认行为,对应f"{obj}",应有合理 fallback
__format__ 和 __str__ 的分工要明确
__str__ 是“默认人类可读表示”,而 __format__ 是“按需定制表示”。不要在 __format__ 里重复写 __str__ 的逻辑,更不要让它返回和 __str__ 完全一样的字符串。
立即学习“Python免费学习笔记(深入)”;
- 错误示范:
def __format__(self, spec): return str(self)—— 失去了自定义意义 - 正确思路:
__str__返回简明摘要,__format__根据spec返回结构化 JSON、带单位的数值、或调试用字段列表 - 注意:如果没定义
__format__,Python 会退回到__str__(仅当format_spec == ''),但一旦定义了,空spec就必须你自己处理
最常被忽略的一点:格式说明符是纯字符串,没有类型信息。哪怕你传 f"{obj:10s}",__format__ 收到的也只是 '10s',不会自动帮你对齐或截断——这些都得你自己用 str.ljust()、textwrap.shorten() 等手动实现。

















