You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带str混合类的Enum使用f-string格式化结果与str()调用不一致问题

底层逻辑解析

核心差异来自__str__和__format__两个特殊方法的调用路径不同

Python官方文档中提到的「空格式说明符f-string输出和str()结果一致」是默认行为,仅适用于没有自定义__format__方法的类:默认的object.__format__逻辑确实是调用str(self)再做格式化。但你的场景中触发了内置类型str的自定义__format__实现,所以出现了差异。


1. str混合Enum的不一致问题解释

你用type=str创建的Enum类,本质上生成的枚举成员同时继承str和Enum两个类,两个特殊方法的查找路径完全不同:

  • 调用str(Mixin.BEE)时,Python优先查找类的__str__方法:Enum类自身实现了__str__(返回类名.枚举名格式),在继承链中优先级高于str的__str__,所以输出Mixin.BEE。
  • 调用f'{Mixin.BEE}'时,Python优先查找类的__format__方法:Enum类没有实现__format__方法,所以继承链上会命中str类的__format__实现,这个方法的逻辑是直接返回str实例存储的原始值(也就是你定义枚举时传入的'BEE'),所以输出BEE。

如果要让两者行为一致,只需要给混合类手动补充__format__实现即可:

Mixin.__format__ = lambda self, spec: format(str(self), spec)

补充后再调用format_vs_str就不会抛出异常。


2. 自定义str子类的异常表现解释

class Foo(str):
    def __str__(self):
        return 'my own str'
foo = Foo()
  • str(foo)和f'{foo}'输出一致:前者直接调用你重写的Foo.__str__;后者查找__format__时命中str.__format__,这个实现会优先调用实例自身的__str__方法,所以返回你自定义的内容。
  • str.__str__(foo)返回空字符串:这是str父类原生方法的逻辑,它会直接返回str实例底层存储的原始字符串值,你创建Foo()时没有传入初始值,所以底层存储的是空字符串,绕过你重写的__str__直接调用父类方法就会返回这个值。如果改成foo = Foo('test'),再调用str.__str__(foo)就会返回'test'。

内容的提问来源于stack exchange,提问作者Kache

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:09:04