dir (obj) 与dir()

📅 2026/7/23 0:35:34
dir (obj) 与dir()
用大白话 代码例子给你讲透先给核心结论这两句话是在说dir(obj)是 Python 内置的「固定规则工具」__dir__()是类里「开发者自定义的钩子」两者的返回结果永远做不到 100% 完全一样而__dir__()返回什么完全由你写的类代码决定没有固定规则。一、先讲第一句「dir (obj) 永远不会和dir() 100% 完全相同」这里的「永远不会 100% 相同」不是指元素内容不一样而是指返回结果的顺序、类型、细节处理永远存在差异核心原因是dir(obj)是 Python 内置的上层封装函数它有自己固定的处理逻辑不管__dir__()返回什么dir()都会做额外的标准化处理导致两者结果不可能完全一致。具体差异体现在 3 个方面1. 顺序永远不同哪怕两者的元素内容完全一样dir()也会做统一排序而__dir__()按类内部的实现顺序返回顺序永远不一样。pythonclass MyClass: def __init__(self): self.name test self.age 18 def __dir__(self): return [name, age] # 自定义顺序 obj MyClass() print(dir(obj)) # 输出[age, name] dir做了排序 print(obj.__dir__()) # 输出[name, age] 按你写的顺序返回2. 类型可能完全不同__dir__()可以返回任何可迭代类型生成器、元组等而dir()永远会把结果转换成标准化的列表类型载体类型完全不同。pythonclass MyClass: def __dir__(self): yield name # 返回生成器 yield age obj MyClass() print(type(obj.__dir__())) # 输出class generator print(type(dir(obj))) # 输出class list3. 细节处理不同dir()会做额外的标准化处理比如去重、过滤极端内部属性而__dir__()返回的是原始内容不会做任何处理。 比如你让__dir__()返回重复元素dir()会自动去重结果就完全不一样了pythonclass MyClass: def __dir__(self): return [name, age, name] # 重复元素 obj MyClass() print(dir(obj)) # 输出[age, name] 自动去重 print(obj.__dir__()) # 输出[name, age, name] 保留原始重复二、再讲第二句「dir() 的返回结果完全由类的实现决定」这句话的意思是__dir__()是类里的魔法方法你在类里怎么写这个方法它就返回什么内容没有任何固定的返回规则完全由开发者自己决定。举几个极端例子你就懂了你可以让__dir__()只返回你指定的 2 个属性不管类里有多少属性pythonclass MyClass: def __init__(self): self.name test self.age 18 self.gender 男 # 这个属性故意不返回 def __dir__(self): return [name, age] # 只返回这两个 obj MyClass() print(obj.__dir__()) # 输出[name, age]你甚至可以让__dir__()返回和类属性完全无关的内容pythonclass MyClass: def __dir__(self): return [我是自定义的, 完全不管类里有什么] obj MyClass() print(obj.__dir__()) # 输出[我是自定义的, 完全不管类里有什么]你可以让__dir__()返回任何类型的可迭代对象pythonclass MyClass: def __dir__(self): return (name, age) # 返回元组 obj MyClass() print(obj.__dir__()) # 输出(name, age)三、最终总结dir(obj)是「固定规则的工具」不管你__dir__()返回什么它都会按自己的逻辑做排序、类型转换、去重等处理所以永远不会和__dir__()的原始结果 100% 完全相同__dir__()是「开发者自定义的钩子」返回什么内容、什么类型、什么顺序完全由你在类里的代码实现决定没有固定规则。