pin_drop当前位置:知识文库 ❯ 图文

Python内置函数dir()

一、dir() 函数简介

dir() 是 Python 的内置函数,用于查看对象的所有属性和方法名称。它是进行对象自省(introspection)的重要工具,在调试、学习和探索 Python 对象时非常有用。

  • 主要用途:快速了解对象有哪些可用的属性和方法

  • 调试利器:在交互式环境中探索未知对象

  • 学习工具:查看模块、类、实例的可用接口


二、语法与参数说明

基本语法

代码示例

dir([object])

参数说明

参数 类型 说明 是否必需
object 任意对象 要查看属性和方法的对象 可选

返回值

返回一个排序后的列表,包含对象的有效属性名称(字符串形式)。如果不传参数,则返回当前作用域内的所有名称。


三、查看内置类型属性

示例1:查看字符串类型

代码示例

# 查看字符串的所有属性和方法
str_methods = dir(str)
print(f"字符串共有 {len(str_methods)} 个属性/方法")

# 过滤出常用方法(非下划线开头)
public_methods = [m for m in str_methods if not m.startswith('_')]
print("字符串的公开方法:")
for method in public_methods[:10]:  # 显示前10个
    print(f"  - {method}")

# 输出示例:
# 字符串共有 70+ 个属性/方法
# 字符串的公开方法:
#   - capitalize
#   - casefold
#   - center
#   - count
#   - encode
#   - endswith
#   - expandtabs
#   - find
#   - format
#   - index

示例2:查看列表类型

代码示例

# 查看列表的所有方法
list_methods = dir(list)
public_methods = [m for m in list_methods if not m.startswith('_')]
print(f"列表的公开方法:{public_methods}")

# 输出: ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

# 查看字典的所有方法
dict_methods = dir(dict)
public_methods = [m for m in dict_methods if not m.startswith('_')]
print(f"字典的公开方法:{public_methods}")

# 输出: ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

四、查看模块内容

示例1:查看内置模块

代码示例

import math

# 查看 math 模块的所有内容
math_contents = dir(math)
print(f"math 模块共有 {len(math_contents)} 个成员")

# 过滤出常量(大写开头)
constants = [m for m in math_contents if m.isupper()]
print(f"math 常量:{constants}")
# 输出: ['inf', 'nan', 'pi', 'tau', 'e']

# 过滤出函数(小写开头)
functions = [m for m in math_contents if m.islower() and not m.startswith('_')]
print(f"math 函数(前5个):{functions[:5]}")
# 输出: ['acos', 'acosh', 'asin', 'asinh', 'atan']

示例2:查看自定义模块

代码示例

# 假设有一个模块 mymodule.py
# 查看模块中定义的所有名称
import mymodule

contents = dir(mymodule)
print(f"mymodule 中的名称:{contents}")

# 过滤出公开的名称(非下划线开头)
public_names = [name for name in contents if not name.startswith('_')]
print(f"公开的名称:{public_names}")

五、查看对象属性和方法

示例1:查看实例对象

代码示例

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def greet(self):
        return f"Hello, I'm {self.name}"
    
    def _private_method(self):
        return "This is private"

# 创建实例
person = Person("Alice", 30)

# 查看实例的所有属性
print(dir(person))
# 输出包含: ['__class__', '__delattr__', ..., '_private_method', 'age', 'greet', 'name']

# 过滤出用户定义的属性和方法
user_attrs = [attr for attr in dir(person) if not attr.startswith('_')]
print(f"用户定义的属性/方法:{user_attrs}")
# 输出: ['age', 'greet', 'name']

示例2:区分属性和方法

代码示例

class Calculator:
    def __init__(self):
        self.result = 0
    
    def add(self, x):
        self.result += x
        return self
    
    def get_result(self):
        return self.result

calc = Calculator()

# 获取所有公开名称
public_attrs = [attr for attr in dir(calc) if not attr.startswith('_')]

# 区分属性和方法
for attr in public_attrs:
    obj = getattr(calc, attr)
    if callable(obj):
        print(f"方法: {attr}")
    else:
        print(f"属性: {attr} = {obj}")

# 输出:
# 属性: result = 0
# 方法: add
# 方法: get_result

六、对象自省与调试

示例1:交互式探索

代码示例

# 在交互式环境中探索未知对象
import datetime

now = datetime.datetime.now()

# 查看 datetime 对象有哪些方法
methods = [m for m in dir(now) if not m.startswith('_')]
print(f"datetime 对象的方法:{methods}")

# 查看某个方法是否可用
if 'strftime' in dir(now):
    formatted = now.strftime("%Y-%m-%d %H:%M:%S")
    print(f"格式化时间:{formatted}")

示例2:检查对象能力

代码示例

def check_capabilities(obj):
    """检查对象支持的操作"""
    capabilities = []
    
    # 检查是否可迭代
    if '__iter__' in dir(obj):
        capabilities.append("可迭代")
    
    # 检查是否可索引
    if '__getitem__' in dir(obj):
        capabilities.append("可索引")
    
    # 检查是否可调用
    if '__call__' in dir(obj):
        capabilities.append("可调用")
    
    # 检查是否有长度
    if '__len__' in dir(obj):
        capabilities.append("有长度")
    
    # 检查是否支持上下文管理
    if '__enter__' in dir(obj) and '__exit__' in dir(obj):
        capabilities.append("支持上下文管理")
    
    return capabilities

# 测试不同类型
print(check_capabilities([1, 2, 3]))  # ['可迭代', '可索引', '有长度']
print(check_capabilities("hello"))    # ['可迭代', '可索引', '有长度']
print(check_capabilities(42))         # []
print(check_capabilities(print))      # ['可调用']

七、自定义类中使用 dir()

示例:自定义 __dir__ 方法

代码示例

class CustomObject:
    def __init__(self):
        self.public_attr = "visible"
        self._private_attr = "hidden"
        self.__very_private = "name mangled"
    
    def public_method(self):
        pass
    
    def _private_method(self):
        pass
    
    def __dir__(self):
        """自定义 dir() 返回的内容"""
        # 只返回公开属性
        return [attr for attr in super().__dir__() if not attr.startswith('_')]

obj = CustomObject()

# 默认 dir() 行为
print("默认 dir():")
print([a for a in dir(obj) if not a.startswith('__')])

# 自定义后的 dir()
print("\n自定义 __dir__() 后:")
print(dir(obj))
# 输出: ['public_attr', 'public_method']

提示:通过重写 __dir__() 方法,可以控制 dir() 返回的内容,这在构建 API 或隐藏内部实现时非常有用。


八、注意事项

注意1dir() 返回的是名称列表,不是属性值。要获取属性值,需要使用 getattr()

代码示例

class MyClass:
    x = 10
    y = 20

obj = MyClass()

# dir() 只返回名称
print(dir(obj))  # 包含 'x', 'y'

# 获取实际值
print(getattr(obj, 'x'))  # 输出: 10
print(getattr(obj, 'y'))  # 输出: 20

注意2dir() 的结果可能包含动态生成的属性,这些属性在每次调用时可能不同。

注意3:不带参数的 dir() 返回当前局部作用域的名称,类似于 locals()

代码示例

# 不带参数的 dir()
a = 1
b = 2
c = 3

print(dir())
# 输出: ['__builtins__', '__name__', '__doc__', '__package__', '__loader__', '__spec__', 'a', 'b', 'c', ...]

九、实际应用技巧

技巧1:快速查找方法

代码示例

# 查找包含特定关键词的方法
def find_methods(obj, keyword):
    """查找对象中包含关键词的方法"""
    methods = [m for m in dir(obj) if keyword.lower() in m.lower()]
    return methods

# 示例:查找字符串中与"替换"相关的方法
print(find_methods(str, "replace"))  # ['replace']
print(find_methods(str, "split"))    # ['rsplit', 'split', 'splitlines']
print(find_methods(list, "sort"))    # ['sort', 'sorted']

技巧2:生成对象文档

代码示例

def generate_object_doc(obj):
    """生成对象的简单文档"""
    print(f"对象类型: {type(obj).__name__}")
    print(f"\n公开属性:")
    
    public_attrs = [a for a in dir(obj) if not a.startswith('_')]
    
    for attr in public_attrs:
        value = getattr(obj, attr, None)
        if callable(value):
            print(f"  方法: {attr}()")
        else:
            print(f"  属性: {attr} = {repr(value)}")

# 使用示例
class Config:
    DEBUG = True
    HOST = "localhost"
    PORT = 8080
    
    def get_url(self):
        return f"http://{self.HOST}:{self.PORT}"

config = Config()
generate_object_doc(config)

技巧3:动态调用方法

代码示例

def dynamic_method_call(obj, method_name, *args, **kwargs):
    """动态调用对象的方法"""
    if method_name in dir(obj):
        method = getattr(obj, method_name)
        if callable(method):
            return method(*args, **kwargs)
        else:
            raise TypeError(f"{method_name} 不是方法")
    else:
        raise AttributeError(f"对象没有 {method_name} 方法")

# 使用示例
text = "hello world"
result = dynamic_method_call(text, "upper")
print(result)  # 输出: HELLO WORLD

result = dynamic_method_call(text, "replace", "world", "Python")
print(result)  # 输出: hello Python

十、常见问题

常见问题

Q1: dir() 和 help() 有什么区别?

dir() 只返回属性和方法的名称列表,而 help() 会显示详细的文档字符串和使用说明。dir() 适合快速查看有哪些接口,help() 适合了解具体用法。

Q2: 为什么 dir() 的结果中有双下划线开头的名称?

双下划线开头和结尾的名称(如 __init____str__)是 Python 的特殊方法(魔术方法),用于实现特定的语言特性。它们通常不需要直接调用,但了解它们有助于深入理解 Python 的工作机制。

Q3: 如何只查看用户定义的属性?

使用列表推导式过滤掉下划线开头的名称:[attr for attr in dir(obj) if not attr.startswith('_')]。这样可以只看到用户定义的公开接口。

Q4: dir() 能显示继承的属性吗?

能。dir() 会显示对象的所有属性,包括从父类继承来的。如果想查看类的 MRO(方法解析顺序),可以使用 ClassName.__mro__ClassName.mro()


十一、练习题

练习1

编写程序,使用 dir() 查看字符串类型的所有方法,并筛选出以 findindex 开头的方法。

练习2

编写一个函数 inspect_object(obj),接收任意对象,打印出该对象的类型、所有公开属性(非下划线开头)以及每个属性的类型(是方法还是数据属性)。

练习3

编写一个类 HiddenAttributes,通过重写 __dir__() 方法,使得 dir() 只返回以 public_ 开头的属性。

标签: dir函数 对象自省 内置函数 调试技巧 属性查看 Python基础

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python chr ord函数 - Unicode与ASCII码转换 下一篇: Python内置函数divmod()

poll相关推荐