pin_drop当前位置:知识文库 ❯ 图文
Python内置函数dir()
目录
一、dir() 函数简介
dir() 是 Python 的内置函数,用于查看对象的所有属性和方法名称。它是进行对象自省(introspection)的重要工具,在调试、学习和探索 Python 对象时非常有用。
-
主要用途:快速了解对象有哪些可用的属性和方法
-
调试利器:在交互式环境中探索未知对象
-
学习工具:查看模块、类、实例的可用接口
二、语法与参数说明
基本语法
代码示例
dir([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 或隐藏内部实现时非常有用。
八、注意事项
注意1:
dir()返回的是名称列表,不是属性值。要获取属性值,需要使用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注意2:
dir()的结果可能包含动态生成的属性,这些属性在每次调用时可能不同。
注意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() 查看字符串类型的所有方法,并筛选出以 find 或 index 开头的方法。
练习2
编写一个函数 inspect_object(obj),接收任意对象,打印出该对象的类型、所有公开属性(非下划线开头)以及每个属性的类型(是方法还是数据属性)。
练习3
编写一个类 HiddenAttributes,通过重写 __dir__() 方法,使得 dir() 只返回以 public_ 开头的属性。
本文涉及AI创作
内容由AI创作,请仔细甄别