__dir__ 方法仅控制 dir() 输出,不影响 ide 补全;补全依赖静态分析(如 __dict__、__annotations__),而非运行时 __dir__;需配合 __getattr__ 等确保属性真实可访问才有效。

__dir__ 方法确实能控制 dir() 返回的内容,但要注意:它**不直接影响 IDE 或 REPL 的补全行为**——那些工具大多依赖静态分析或 __dict__,而非运行时调用 __dir__。想让补全“看起来有效”,得配合实际属性存在或动态代理。
为什么重写 __dir__ 后补全没反应?
多数编辑器(VS Code、PyCharm)在编辑时不会执行你的 __dir__,而是扫描类定义、__annotations__、__dict__ 和已知的魔术方法。即使你返回了 ['foo', 'bar'],如果实例没有对应属性,补全也不会显示它们。
- IDE 补全靠的是“静态可推断性”,不是运行时
dir()结果 -
__dir__主要影响交互式环境(如 IPython)中手动敲dir(obj)的输出 - 若属性是动态生成的(比如通过
__getattr__),必须确保__dir__返回的名称也真实可访问,否则补全会误导人
怎样让 __dir__ 真正有用?
让它反映真实可用的属性,尤其配合 __getattr__ 实现动态属性时:
class Config:
def __init__(self, data):
self._data = data
<pre class="brush:python;toolbar:false;">def __getattr__(self, name):
if name in self._data:
return self._data[name]
raise AttributeError(f"'Config' object has no attribute '{name}'")
def __dir__(self):
# 合并内置属性 + 动态键
return sorted(set(super().__dir__()) | set(self._data.keys()))
-
super().__dir__()保留默认方法和属性(如__class__、__init__) - 用
set去重,避免重复项干扰补全列表 - 返回
list,不能是生成器或元组——dir()要求返回序列
哪些场景下 __dir__ 会被真正调用?
主要出现在交互式调试和文档生成中:
- IPython / Jupyter 中敲
obj.<tab></tab>有时会触发(取决于后端配置) -
help(obj)会用到dir(obj)的结果来筛选展示内容 - 某些自动化文档工具(如 Sphinx 的 autodoc)可能读取
__dir__来决定列出哪些成员 - 单元测试里用
assert 'x' in dir(obj)检查接口可见性
真正影响补全的,还是让属性“物理存在”——要么直接赋值到 self.x,要么用 @property,要么配合 __getattr__ + __dir__ 保持一致。否则,__dir__ 只是个好看的幻觉。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











