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

为何类对象的dir()输出中不包含__mro__与mro属性?

为什么dir(C)不显示__mro__和mro属性?

先看这段代码:

class C:
    pass

print(C.mro())  # 输出: [<class '__main__.C'>, <class 'object'>]
print(C.__mro__)  # 输出: (<class '__main__.C'>, <class 'object'>)
print(dir(C))  # 输出内容过长 :( 
print("__mro__" in dir(C) or "mro" in dir(C))  # 输出: False

明明mro和__mro__是类C的有效属性,能正常调用和访问,为什么它们没有出现在dir()函数的输出里?

有人解释说__mro__和mro是元类type的属性(类C是type的实例),而非C的超类属性,所以type的__dict__不会被合并到dir(C)的结果中。但这里有个疑问,看对比代码:

class Sample:
    a = 5
    def f():
        pass

s = Sample()
print(dir(s))   # 输出内容过长
print("f" in dir(s))  # 输出: True
print("a" in dir(s))  # 输出: True

实例s是Sample的实例,Sample的属性能出现在dir(s)中;那类C是type的实例,按这个逻辑,type的__mro__和mro也应该出现在dir(C)中才对,可实际并没有。这是为什么?


核心原因:dir()函数对「类(元类实例)」和「普通实例」的处理逻辑不同

  1. 普通实例的dir()逻辑
    当调用dir(s)(s是Sample的实例)时,dir()会:
  • 先收集实例自身__dict__中的属性
  • 再递归收集实例所属类(Sample)及其所有父类的__dict__中的属性
    所以Sample的类属性a和方法f会被包含在dir(s)的结果里。
  1. 类(元类实例)的dir()逻辑
    当调用dir(C)(C是type的实例)时,dir()会:
  • 先收集类自身__dict__中的属性
  • 再递归收集类的所有父类(这里是object)的__dict__中的属性
    但不会去收集元类(type)及其父类的__dict__中的属性
  1. 属性查找 vs dir()的区别
    你能正常调用C.mro()或访问C.__mro__,是因为Python的属性查找机制和dir()的逻辑不一样:
  • 属性查找时,访问类的属性会遵循「类自身→父类→元类→元类父类」的顺序,所以能找到type里的mro和__mro__
  • 但dir()的设计目标是展示「类/实例自身以及继承链上的属性」,这里的继承链指的是类的父类链,而非元类链,所以不会包含元类的属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:57:03