前言

在学习一个新的 Python 包时,我们经常想快速了解它有哪些模块和子包。本文分享一个简单实用的小工具,帮你一键生成包的模块结构树。


完整代码

#!/usr/bin/env python3
"""
包结构探测器 - 快速查看任意Python包的模块结构
"""
import argparse
import importlib
import pkgutil
import sys


def probe_package(package_name, max_depth=3):
    """
    探测包结构并打印模块树
    
    Args:
        package_name: 包名
        max_depth: 最大探测深度
    """
    # 导入包
    try:
        root = importlib.import_module(package_name)
    except ModuleNotFoundError:
        print(f"❌ 找不到包: {package_name}")
        print(f"   请先安装: pip install {package_name}")
        return
    except Exception as e:
        print(f"❌ 导入失败: {e}")
        return
    
    # 收集所有模块
    modules = [root.__name__]
    
    if hasattr(root, "__path__"):
        # 是一个包,遍历子模块
        def walk(pkg, depth=0):
            if depth >= max_depth:
                return
            try:
                for finder, name, ispkg in pkgutil.iter_modules(pkg.__path__, pkg.__name__ + "."):
                    modules.append(name)
                    if ispkg:
                        try:
                            sub = importlib.import_module(name)
                            walk(sub, depth + 1)
                        except:
                            pass
            except:
                pass
        
        walk(root)
    
    # 打印结果
    print(f"\n📦 {package_name} 模块结构")
    print("=" * 40)
    
    # 构建树形结构
    root_name = package_name
    for mod_name in sorted(modules):
        # 计算缩进
        depth = mod_name.count('.') - root_name.count('.')
        indent = "    " * depth
        
        # 取最后一段名称
        short_name = mod_name.split('.')[-1]
        
        # 判断是包还是模块
        try:
            mod = importlib.import_module(mod_name)
            is_pkg = hasattr(mod, "__path__")
            icon = "📁" if is_pkg else "📄"
        except:
            icon = "📄"
        
        print(f"{indent}{icon} {short_name}")
    
    print("=" * 40)
    print(f"共 {len(modules)} 个模块\n")


def main():
    parser = argparse.ArgumentParser(description="查看Python包的模块结构")
    parser.add_argument("package", help="包名")
    parser.add_argument("-d", "--depth", type=int, default=3, help="最大深度(默认3)")
    
    args = parser.parse_args()
    probe_package(args.package, args.depth)


if __name__ == "__main__":
    main()

使用方法

基础用法

python probe_pkg.py requests

输出:

📦 requests 模块结构
========================================
📁 requests
    📄 adapters
    📄 api
    📄 auth
    📄 certs
    📄 compat
    📄 cookies
    📄 exceptions
    📄 hooks
    📄 models
    📄 sessions
    📄 status_codes
    📄 structures
    📄 utils
========================================
共 14 个模块

控制探测深度

python probe_pkg.py urllib3 -d 2

更多示例

# 探测 flask
python probe_pkg.py flask

# 探测 numpy(内容较多,限制深度)
python probe_pkg.py numpy -d 1

# 探测本地开发的包
python probe_pkg.py myproject

代码解析

核心原理

  1. importlib.import_module() - 动态导入指定的包
  2. pkgutil.iter_modules() - 遍历包内的所有子模块
  3. __path__属性 - 判断是包(有__path__)还是普通模块

关键代码片段

# 判断是包还是模块
if hasattr(module, "__path__"):
    print("这是一个包,可以包含子模块")
else:
    print("这是一个普通模块")

# 遍历子模块
for finder, name, ispkg in pkgutil.iter_modules(pkg.__path__):
    print(f"发现: {name}, 是否为包: {ispkg}")

实用技巧

1. 快速了解新包

拿到一个新包,先跑一遍探测器,对整体结构有个概念:

python probe_pkg.py some_new_package

2. 配合 help() 使用

找到感兴趣的模块后,用 help() 查看详情:

import requests.adapters
help(requests.adapters)

3. 项目自检

检查自己项目的模块组织是否合理:

python probe_pkg.py myproject -d 5

总结

这个小工具虽然简单,但在日常开发中非常实用:

  • ✅ 快速了解包结构
  • ✅ 学习新库的起点
  • ✅ 检查项目模块组织
  • ✅ 代码量少,易于修改扩展

把它保存为 probe_pkg.py,放到常用工具目录,随时调用!


💡 扩展思路:可以加入导出 Markdown、显示模块文档、统计代码行数等功能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐