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

继承dict的类为何不按MRO优先级调用dict.__str__?

Python多继承下__str__方法的MRO异常及3.12版本Bug说明

问题场景

定义同时继承dict和自定义类A的类B,其MRO顺序为B → dict → A → object,但调用str(B())时返回的是A中定义的字符串"A",而非dict默认的"{}"。疑问点在于:为何没有按照MRO的优先级调用dict.__str__?这是否和dict.__str__是slot wrapper而非普通函数有关?

示例代码(Python 3.10.12环境)

>>> class A:
...  def __str__(self):
...   return "A"
...
>>> class B(dict, A):
...  pass
...
>>> B.__mro__
(<class '__main__.B'>, <class 'dict'>, <class '__main__.A'>, <class 'object'>)
>>> str(B())
'A'
>>> str(dict())
'{}'
>>> dict.__str__
<slot wrapper '__str__' of 'object' objects>
>>> A.__str__
<function A.__str__ at 0x75be4ea8a0e0>
>>> B.__str__
<function A.__str__ at 0x75be4ea8a0e0>

原因解析

这一现象和Python对内置类型特殊方法的处理机制直接相关:

  • dict的__str__是通过slot wrapper实现的内置方法,这类方法并非存储在dict类的方法字典中,而是属于底层实现的槽位方法。
  • 自定义类A的__str__是Python层面的普通函数,会被纳入类的方法字典。
  • 在多继承的方法合并过程中,Python会优先将普通函数形式的方法保留到子类的类属性中,内置类型的slot方法不会被自动继承到子类的方法字典。因此B.__str__最终指向的是A.__str__,调用str(B())时自然会执行A中的逻辑,而非按MRO顺序调用dict.__str__。

Python 3.12子解释器的特殊问题

在Python 3.12及3.12.4之前的版本中,子解释器环境下dict.__str__的显示变为dict对象的slot wrapper,这会导致Django表单的错误显示出现异常。该问题是Python官方已知Bug,可通过设置WSGIApplicationGroup %{GLOBAL}强制使用全局解释器来修复,后续版本已修复该问题(Bug编号:gh-117482)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:04:55