一、概述
在 Python 中,有多种方法可以查看模块中包含的变量、函数、类等信息。这些方法对于探索新模块、调试代码和理解模块结构非常有帮助。
二、使用 dir() 函数
1. 基本用法
import mathimport sys# 查看模块的所有属性和方法print(dir(math))print(dir(sys))# 查看当前模块的内容print(dir())# 查看特定对象的属性和方法x = "hello"print(dir(x))# 列表对象的方法lst = [1, 2, 3]print(dir(lst))
2. 过滤私有成员
import math# 查看所有成员all_members = dir(math)print(f"总共 {len(all_members)} 个成员")# 过滤出公共成员(不以 _ 开头)public_members = [m for m in dir(math) if not m.startswith('_')]print(f"公共成员: {public_members[:10]}...")# 过滤出私有成员(以 _ 开头)private_members = [m for m in dir(math) if m.startswith('_')]print(f"私有成员: {private_members[:10]}...")# 过滤出魔法方法(以 __ 开头和结尾)magic_methods = [m for m in dir(math) if m.startswith('__') and m.endswith('__')]print(f"魔法方法: {magic_methods[:10]}...")
3. 区分不同类型的成员
import mathdef categorize_members(module): """分类模块中的成员""" categories = { 'functions': [], 'classes': [], 'variables': [], 'others': [] } for name in dir(module): if name.startswith('_'): # 跳过私有成员 continue obj = getattr(module, name) if callable(obj): # 检查是否是类还是函数 if isinstance(obj, type): categories['classes'].append(name) else: categories['functions'].append(name) else: categories['variables'].append(name) return categories# 分析 math 模块result = categorize_members(math)for category, items in result.items(): print(f"{category}: {items[:5]}...")
三、使用 __dict__ 属性
1. 查看模块的命名空间
import math# 查看模块的字典print(math.__dict__.keys())print(f"模块字典大小: {len(math.__dict__)}")# 查看特定类型的内容module_dict = math.__dict__functions = {k: v for k, v in module_dict.items() if callable(v) and not k.startswith('_')}print(f"函数: {list(functions.keys())[:5]}")# 自定义模块的 __dict__# mymodule.pyx = 10y = 20def add(a, b): return a + bclass MyClass: pass# 查看自定义模块的 __dict__import mymoduleprint(mymodule.__dict__.keys())# dict_keys(['__name__', '__doc__', '__package__', ..., 'x', 'y', 'add', 'MyClass'])
2. 查看类和实例的 __dict__
class Person: class_attr = "类属性" def __init__(self, name, age): self.name = name self.age = age self._private = "私有属性" def greet(self): return f"Hello, {self.name}"# 查看类的 __dict__print("类字典:")for key, value in Person.__dict__.items(): if not key.startswith('__'): print(f" {key}: {value}")# 查看实例的 __dict__p = Person("Alice", 25)print("\n实例字典:")for key, value in p.__dict__.items(): print(f" {key}: {value}")# 添加新属性p.email = "alice@example.com"print(f"\n添加后: {p.__dict__}")
四、使用 inspect 模块
1. 检查模块成员
import inspectimport mathdef analyze_module(module): """使用 inspect 模块分析模块""" print(f"分析模块: {module.__name__}") print("=" * 50) # 获取所有成员 members = inspect.getmembers(module) # 分类统计 functions = [] classes = [] variables = [] for name, obj in members: if name.startswith('_'): # 跳过私有成员 continue if inspect.isfunction(obj): functions.append(name) elif inspect.isclass(obj): classes.append(name) elif not callable(obj): variables.append(name) print(f"函数 ({len(functions)}): {functions[:5]}...") print(f"类 ({len(classes)}): {classes[:5]}...") print(f"变量 ({len(variables)}): {variables[:5]}...")analyze_module(math)
2. 获取函数签名和文档
import inspectimport mathdef inspect_function(module, func_name): """检查特定函数的详细信息""" obj = getattr(module, func_name) print(f"检查函数: {func_name}") print("=" * 50) # 函数签名 try: sig = inspect.signature(obj) print(f"签名: {func_name}{sig}") except (ValueError, TypeError): print("无法获取签名") # 文档字符串 doc = inspect.getdoc(obj) if doc: print(f"\n文档:\n{doc[:200]}...") else: print("\n无文档字符串") # 源代码位置 try: source_file = inspect.getsourcefile(obj) print(f"\n源代码文件: {source_file}") except TypeError: print("无法获取源文件位置")# 检查 math.sqrt 函数inspect_function(math, 'sqrt')# 检查自定义函数def my_function(x, y=10, *args, **kwargs): """这是一个示例函数""" return x + yinspect_function(inspect, 'getmembers') # 检查 inspect.getmembers
3. 获取类的层次结构
import inspectclass Animal: passclass Mammal(Animal): passclass Dog(Mammal): passdef show_class_hierarchy(cls): """显示类的继承层次""" print(f"类继承链: {cls.__name__}") # 获取所有基类 for i, base in enumerate(inspect.getmro(cls)): indent = " " * i print(f"{indent}└─ {base.__name__}") # 获取所有子类 print(f"\n{cls.__name__} 的子类:") for subclass in cls.__subclasses__(): print(f" └─ {subclass.__name__}")show_class_hierarchy(Dog)print()show_class_hierarchy(int)
五、使用 help() 函数
1. 交互式帮助
# 在交互式环境中使用# help(math) # 查看 math 模块的完整帮助# help(math.sqrt) # 查看 sqrt 函数的帮助# help(str) # 查看字符串类的帮助# 在脚本中获取帮助文本import mathimport sysfrom io import StringIOdef get_help_text(obj): """获取对象的帮助文本""" # 重定向标准输出 old_stdout = sys.stdout sys.stdout = StringIO() help(obj) # 获取输出内容 help_text = sys.stdout.getvalue() sys.stdout = old_stdout return help_text# 获取 math.sqrt 的帮助sqrt_help = get_help_text(math.sqrt)print("math.sqrt 帮助信息(前500字符):")print(sqrt_help[:500])
六、使用 pydoc 模块
1. 生成文档
# 在命令行中使用 pydoc# python -m pydoc math # 查看 math 模块文档# python -m pydoc -p 1234 # 启动文档服务器# python -m pydoc -w math # 生成 HTML 文档# 在代码中获取文档import pydocdef get_module_doc(module_name): """获取模块的文档字符串""" module = __import__(module_name) return pydoc.render_doc(module)# math_doc = get_module_doc('math')# print("math 模块文档长度:", len(math_doc))
七、总结
查看模块内容的方法对比
| | | |
|---|
dir() | | | |
__dict__ | | | |
inspect | | | |
help() | | | |
pydoc | | | |
最佳实践示例
# 完整的模块检查示例def explore_module(module_name): """探索模块的完整函数""" import inspect import sys try: module = __import__(module_name) except ImportError: print(f"无法导入模块: {module_name}") return print(f"=== 探索模块: {module_name} ===") # 1. 基本信息 print(f"\n1. 基本信息:") print(f" 文件: {getattr(module, '__file__', 'N/A')}") print(f" 文档: {getattr(module, '__doc__', 'N/A')[:100]}...") # 2. 成员分类 print(f"\n2. 成员统计:") members = inspect.getmembers(module) stats = { 'functions': 0, 'classes': 0, 'variables': 0, 'modules': 0 } for name, obj in members: if name.startswith('_'): # 跳过私有成员 continue if inspect.isfunction(obj): stats['functions'] += 1 elif inspect.isclass(obj): stats['classes'] += 1 elif inspect.ismodule(obj): stats['modules'] += 1 elif not callable(obj): stats['variables'] += 1 for key, value in stats.items(): print(f" {key}: {value}") # 3. 函数签名示例 print(f"\n3. 函数签名示例:") funcs = [name for name, obj in inspect.getmembers(module) if inspect.isfunction(obj) and not name.startswith('_')] for func_name in funcs[:3]: func = getattr(module, func_name) try: sig = inspect.signature(func) print(f" {func_name}{sig}") except: print(f" {func_name}(...)") # 4. 类层次示例 print(f"\n4. 类信息示例:") classes = [name for name, obj in inspect.getmembers(module) if inspect.isclass(obj) and not name.startswith('_')] for class_name in classes[:3]: cls = getattr(module, class_name) bases = [base.__name__ for base in cls.__bases__ if base != object] if bases: print(f" {class_name}({', '.join(bases)})") else: print(f" {class_name}") print("\n探索完成!")# 使用示例explore_module('math')
如何查看模块内容对于学习和使用 Python 非常重要。通过 dir()、inspect 等工具,可以快速了解模块提供的功能,提高开发效率。