摘要:在 Python 中,格式化协议(Formatting Protocol)决定了一个对象在参与字符串格式化操作时的行为。它让开发者能够自定义对象被 format 函数、str.format 方法或 f-string 语法格式化时的表现。
在 Python 中,格式化协议(Formatting Protocol)决定了一个对象在参与字符串格式化操作时的行为。它让开发者能够自定义对象被 format 函数、str.format 方法或 f-string 语法格式化时的表现。
该协议由一个核心特殊方法构成:__format__(self, format_spec),并与 __str__、__repr__ 一同构成 Python 对象的字符串表达体系。
一、格式化协议及其作用
Python 官方文档(Data model — Special method names)对 __format__ 的定义如下:
object.__format__(self, format_spec)
Called by the built-in format function and by str.format and f-strings to produce a “formatted” string version of the object.
即:
内置函数 format、字符串方法 str.format 以及 f-string 格式化操作在执行时,都会调用对象的 __format__ 方法来生成格式化字符串。
设计目的:
提供比 __str__ 更灵活的输出控制;
支持自定义格式说明符(format_spec);
统一各种字符串格式化机制的底层逻辑。
“格式化协议”虽未正式被官方命名,但普遍存在于语言机制与实践中,是事实上的“协议”。
二、基本语法与调用规则
格式化协议的语法统一为:
format(value, format_spec)或等价的形式:
"{:format_spec}".format(value)f"{value:format_spec}"在执行时,Python 实际上会自动调用:
value.__format__(format_spec)若对象未定义 __format__,则 Python 会使用其 __str__ 的结果作为回退输出。
三、示例:内置类型的格式化行为
Python 内置类型均实现了 __format__,支持丰富的格式控制。
1、数值类型
print(f"{x:>10.1f}") # ' 123.5'2、整数的进制格式
}") # 0x2a (带前缀的十六进制)3、日期与时间类型
datetime 模块的对象也实现了 __format__,支持自定义格式说明符:
print(format(now, "%Y/%m/%d")) # 2025/10/28四、自定义类实现格式化协议
我们可以在自定义类中定义 __format__,从而支持特定格式说明符。
print(f"{p:r}") # r=5.00, θ=53.1°通过这种机制,自定义对象也能像内置类型一样灵活格式化。
五、与字符串表示协议的关系
__format__ 与 __str__、__repr__ 一样,都属于字符串输出相关的协议,但它的职责更广:
方法
调用时机
输出目的
可带格式
说明符
常见使用
__repr__
调试、交互模式
精确表示(开发者视角)
repr(obj)__str__
用户输出
可读表示(用户视角)
str(obj)__format__
字符串格式化
f-string
可控格式化(灵活)
format(obj)
f"{obj:spec}"
如果未定义 __format__,Python 会默认调用 __str__ 的结果。
因此,可以认为 __format__ 是对字符串表示协议的扩展和增强。
六、扩展示例:复数格式化
print(f"{z:polar}") # 5.00∠0.93rad在工程或科学计算场景中,这种方式可以显著提升对象的可读性与可控性。
小结
格式化协议是 Python 对象模型中控制输出格式的核心机制。
它使得所有对象都能通过同一接口灵活定义自己的格式化表现。
__format__(self, format_spec) 是协议核心;
被 format、str.format 和 f-string 调用;
内置类型已实现丰富格式说明符;
用户可自定义 format_spec 规则;
未定义时自动回退到 __str__;
它与字符串表示协议共同构成对象输出体系。
__str__ 让对象“能说话”;__format__ 让对象“会表达”。
“点赞有美意,赞赏是鼓励”
来源:雯婷教育
