ZetCode

Python dir 函数

上次修改时间:2025 年 4 月 11 日

本综合指南探讨了 Python 的 dir 函数,该函数返回对象有效属性的列表。我们将涵盖基本用法、自定义对象和对象内省的实际示例。

基本定义

dir 函数返回当前本地作用域中的名称或对象属性的排序列表。不带参数时,它列出当前作用域中的名称。

主要特点:返回字符串,适用于任何对象,包括特殊方法(双下划线方法),并且可以通过 __dir__ 进行自定义。

不带参数的基本用法

当不带参数调用时,dir 列出当前本地作用域中的名称。此示例显示了它在不同上下文中的行为。

basic_dir.py
# In global scope
print(dir())  # Lists global names (like '__name__', '__doc__', etc.)

def test_function():
    x = 10
    y = 20
    print(dir())  # Lists local names ('x', 'y')

test_function()

第一个 dir() 调用显示全局名称,而函数内部的调用显示局部变量。这有助于调试作用域问题。

请注意,默认情况下不包含内置名称。使用 dir(__builtins__) 查看它们。

检查模块内容

dir 通常用于探索模块内容。此示例显示了如何检查 math 模块的属性。

module_inspection.py
import math

# Get all attributes of math module
math_attrs = dir(math)
print(math_attrs[:10])  # First 10 attributes

# Filter out dunder methods
public_attrs = [attr for attr in math_attrs if not attr.startswith('__')]
print(public_attrs[:5])  # ['acos', 'acosh', 'asin', 'asinh', 'atan']

这列出了 math 模块中的所有属性,然后过滤以仅显示公共属性。这对于发现模块功能很有用。

该示例演示了如何处理 dir 输出以专注于相关属性。

带有 __dir__ 的自定义对象

您可以通过在类中实现 __dir__ 来自定义 dir 的输出。此示例创建了一个自定义类。

custom_dir.py
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __dir__(self):
        return ['name', 'age', 'greet']
    
    def greet(self):
        return f"Hello, I'm {self.name}"

p = Person("Alice", 30)
print(dir(p))  # ['age', 'greet', 'name']

Person__dir__ 来控制列出哪些属性。这为用户提供了更清晰的界面。

请注意,__dir__ 应该返回一个字符串列表,Python 会自动对输出进行排序。

探索对象层次结构

dir 通过显示所有父类的属性来揭示继承结构。此示例演示了继承内省。

inheritance.py
class Animal:
    def __init__(self, species):
        self.species = species
    
    def eat(self):
        print("Eating...")

class Dog(Animal):
    def __init__(self, name):
        super().__init__("Canine")
        self.name = name
    
    def bark(self):
        print("Woof!")

d = Dog("Rex")
print(dir(d))  # Includes Animal and Dog attributes

输出显示了 Dog 及其父类 Animal 的属性。这有助于理解复杂的类层次结构。

所有祖先的特殊方法(例如 __init__)也包含在列表中。

过滤 dir 输出

此示例显示了如何过滤和分析 dir 输出以查找特定类型的属性。

filter_dir.py
class Example:
    def __init__(self):
        self.public = 1
        self._protected = 2
        self.__private = 3
    
    def method(self):
        pass
    
    @property
    def prop(self):
        return self.public

e = Example()

# Get all attributes
attrs = dir(e)

# Filter by type
methods = [a for a in attrs if callable(getattr(e, a))]
properties = [a for a in attrs if isinstance(getattr(type(e), a, None), property)]
private = [a for a in attrs if a.startswith('_Example__')]

print("Methods:", methods)
print("Properties:", properties)
print("Name-mangled private:", private)

这演示了用于对属性进行分类的高级 dir 用法。我们过滤方法、属性和名称修饰的私有属性。

这种分析对于元编程、文档生成和调试复杂对象很有用。

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程