dir (obj) 与dir()

大白话 + 代码例子给你讲透,先给核心结论:

这两句话是在说:dir(obj) 是 Python 内置的「固定规则工具」,__dir__() 是类里「开发者自定义的钩子」,两者的返回结果永远做不到 100% 完全一样;而__dir__()返回什么,完全由你写的类代码决定,没有固定规则。


一、先讲第一句:「dir (obj) 永远不会和 dir() 100% 完全相同」

这里的「永远不会 100% 相同」,不是指元素内容不一样,而是指返回结果的顺序、类型、细节处理,永远存在差异 ,核心原因是: dir(obj) 是 Python 内置的上层封装函数 ,它有自己固定的处理逻辑,不管__dir__()返回什么,dir()都会做额外的标准化处理,导致两者结果不可能完全一致。

具体差异体现在 3 个方面:

1. 顺序永远不同

哪怕两者的元素内容完全一样,dir()也会做统一排序 ,而__dir__()按类内部的实现顺序返回,顺序永远不一样。

python

复制代码
class 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()永远会把结果转换成标准化的列表类型,载体类型完全不同。

python

复制代码
class MyClass:
    def __dir__(self):
        yield "name"  # 返回生成器
        yield "age"

obj = MyClass()
print(type(obj.__dir__()))  # 输出:<class 'generator'>
print(type(dir(obj)))       # 输出:<class 'list'>
3. 细节处理不同

dir()会做额外的标准化处理(比如去重、过滤极端内部属性),而__dir__()返回的是原始内容,不会做任何处理。 比如你让__dir__()返回重复元素,dir()会自动去重,结果就完全不一样了:

python

复制代码
class MyClass:
    def __dir__(self):
        return ["name", "age", "name"]  # 重复元素

obj = MyClass()
print(dir(obj))       # 输出:['age', 'name'] (自动去重)
print(obj.__dir__())  # 输出:['name', 'age', 'name'] (保留原始重复)

二、再讲第二句:「dir() 的返回结果,完全由类的实现决定」

这句话的意思是:__dir__()是类里的魔法方法,你在类里怎么写这个方法,它就返回什么内容,没有任何固定的返回规则,完全由开发者自己决定。

举几个极端例子,你就懂了:

  1. 你可以让__dir__()只返回你指定的 2 个属性,不管类里有多少属性:

python

复制代码
class 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']
  1. 你甚至可以让__dir__()返回和类属性完全无关的内容:

python

复制代码
class MyClass:
    def __dir__(self):
        return ["我是自定义的", "完全不管类里有什么"]

obj = MyClass()
print(obj.__dir__())  # 输出:['我是自定义的', '完全不管类里有什么']
  1. 你可以让__dir__()返回任何类型的可迭代对象:

python

复制代码
class MyClass:
    def __dir__(self):
        return ("name", "age")  # 返回元组

obj = MyClass()
print(obj.__dir__())  # 输出:('name', 'age')

三、最终总结

  1. dir(obj) 是「固定规则的工具」,不管你__dir__()返回什么,它都会按自己的逻辑做排序、类型转换、去重等处理,所以永远不会和__dir__()的原始结果 100% 完全相同
  2. __dir__() 是「开发者自定义的钩子」,返回什么内容、什么类型、什么顺序,完全由你在类里的代码实现决定,没有固定规则。
相关推荐
WWJA王文举17 分钟前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
zhanghaha13141 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json
qq_448011162 小时前
C语言中的动态内存分配
c语言·开发语言·php
汉字萌萌哒3 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
arbboter3 小时前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
汉字萌萌哒4 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
叠层归一研究院4 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
小雨笙笙4 小时前
C语言:变量三属性——存储类型
c语言·开发语言
果果燕5 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++
江畔柳前堤5 小时前
Function Calling 与 Tool Calling:从认知到工程的全景深度解析
开发语言·网络·人工智能·深度学习·算法·机器学习·php