小众python库的方法与文档接口查看

该文章已生成可运行项目,

问题场景

小众开发者的仓库,没有做文档,直接上源码,源码太长但好在源码里夹带着注释和文档,

你需要清楚地知道每一个类、每一个属性、方法的输入、输出,以及功能是什么?

有没有省时省力一点提取注释文档的方法?

此处我以某个计算生物学库aiupred_lib为例,比较小众,开发者没怎么给文档+源码有一点点长

一般计算生物学的库, 其实实现的规范没有计算机那么严谨,
一般文档中说import XXX, 其实就是该软件安装路径下有个XXX.py.
以aiupred_lib为例, 就是该仓库软件下载解压文件夹下有一个aiupre_lib.py

要一次性输出 aiupred_lib 库中所有方法(含函数、类、类方法等)及其对应文档,核心是利用 Python 内置的反射机制(如 dir()getattr())和文档提取工具(如 inspect 模块)。

下面本博客就是分场景的完整实现方案,覆盖库的所有可调用成员,并清晰展示文档信息。

核心原理

  1. dir(aiupred_lib):获取库中所有成员名称(包括函数、类、变量等)。
  2. inspect 模块:过滤出「可调用对象」(排除普通变量),并提取其详细文档( docstring )、参数列表等信息。
  3. 分类输出:区分「顶层函数」和「类及其方法」,避免信息混乱(库中通常包含类,类内部又有方法)。

参考:https://github.com/MaybeBio/bioinfor_script_modules/blob/main/38_Library_Doc_interface.py

step1:导入必要模块并加载目标库

首先确保 aiupred_lib 已安装且可导入(若需添加路径,可结合 sys.path 逻辑):

参考之前的博客:https://blog.youkuaiyun.com/weixin_62528784/article/details/149749704?spm=1001.2014.3001.5502

假设安装路径为/path/to/aiupred/folder

# 1, 在终端中, 需要
export PYTHONPATH="${PYTHONPATH}:/path/to/aiupred/folder"
如果PYTHONPATH为空, 则直接export PYTHONPATH="/path/to/aiupred/folder"
可以在	~/.bashrc或者是~/.zshrc中修改

# 2, 在Notebook中
AIUpred_PATH = "/path/to/aiupred/folder"
if AIUpred_PATH not in sys.path:
    sys.path.append(AIUpred_PATH)
import aiupred_lib
import sys
import os
import inspect  # 核心:用于提取对象信息和文档

# 导入目标库
import aiupred_lib  # 确保这行不报错,否则需检查路径或库安装
step2:定义工具函数(提取文档+过滤可调用对象)

封装两个核心工具函数,简化后续逻辑:

def get_object_doc(obj, obj_name: str) -> str:
    """提取对象的文档信息(docstring + 参数列表)"""
    # 1. 提取docstring(若没有文档,返回提示)
    docstring = inspect.getdoc(obj) or "⚠️ 无官方文档"
    
    # 2. 提取参数列表(针对函数/方法)
    try:
        # 获取签名(参数名、默认值等)
        sig = inspect.signature(obj)
        params_info = f"参数列表: {str(sig)}"
    except (ValueError, TypeError):
        # 非函数/方法(如类本身),无参数列表
        params_info = "❌ 非可调用对象,无参数列表"
    
    # 3. 组合文档信息
    return f"""
【{obj_name}{params_info}
------------------------------
文档说明:
{docstring}
======================================================================"""


def is_callable_member(member) -> bool:
    """过滤:仅保留「可调用对象」(函数、类、类方法等),排除普通变量"""
    # 排除内置特殊成员(如 __name__、__doc__)
    if inspect.ismodule(member):
        return False  # 排除子模块(若库包含子模块,可按需调整)
    # 保留:函数、类、实例方法、类方法、静态方法
    return (inspect.isfunction(member) 
            or inspect.isclass(member) 
            or inspect.ismethod(member) 
            or inspect.ismethoddescriptor(member))
step3:遍历库成员,分类输出所有方法及文档

分「顶层函数/类」和「类的内部方法」两类输出,结构更清晰:

def print_all_methods_with_docs(library) -> None:
    """主函数:输出库中所有可调用成员及其文档"""
    print(f"=== 开始输出 {library.__name__} 库的所有方法及文档 ===")
    print(f"库路径: {library.__file__}\n")

    # 1. 获取库的所有成员名称(过滤掉内置特殊成员,如 __init__)
    all_member_names = [name for name in dir(library) if not name.startswith("__")]

    # 2. 遍历成员,分类处理
    for member_name in all_member_names:
        # 获取成员对象(如函数、类)
        member = getattr(library, member_name)
        
        # 过滤:仅处理可调用对象
        if not is_callable_member(member):
            continue

        # 场景A:成员是「类」(需进一步输出类的内部方法)
        if inspect.isclass(member):
            print(f"📦 类: {member_name}")
            print(get_object_doc(member, member_name))  # 输出类本身的文档
            
            # 提取类的所有方法(过滤内置特殊方法)
            class_methods = [
                meth_name for meth_name in dir(member) 
                if not meth_name.startswith("__")
            ]
            for meth_name in class_methods:
                meth = getattr(member, meth_name)
                if is_callable_member(meth):  # 确保是方法(而非类变量)
                    print(f"  🔧 方法: {member_name}.{meth_name}")
                    print(get_object_doc(meth, f"{member_name}.{meth_name}"))

        # 场景B:成员是「顶层函数」(直接输出)
        else:
            print(f"🔧 顶层函数: {member_name}")
            print(get_object_doc(member, member_name))

    print(f"=== {library.__name__} 库所有方法及文档输出完毕 ===")


# 执行主函数,输出结果
if __name__ == "__main__":
    print_all_methods_with_docs(aiupred_lib)

比如说我这里的文档查看:

如果是朴素的方法,

如果只是看用dir方法或者inspect模块:先dir查看,再细节用inspect模块

比如说这里有一个’calculate_energy’,再用inspect模块中的方法查看:

或者直接用help:

未免显得太麻烦了,其实就是效率和效果不好。

如果想要高屋建瓴的概览,直接查看整个库的帮助文档,

写得短一点还好,直接硬啃即可,写得长一点就麻烦了。

所以用上面自定义函数的方法,1个1个地提取,效果如下:

写得有点问题,中间transformer类输出方法冗余有点多,后续矫正一下。

一般直接看顶层函数即可

关键注意事项

  1. 处理「子模块」:若 aiupred_lib 包含子模块(如 aiupred_lib.models),上述代码仅输出顶层成员。若需包含子模块,需在 is_callable_member 中移除 inspect.ismodule(member) 的判断,并递归遍历子模块(可留言补充需求)。
  2. 文档完整性:输出的文档依赖库本身是否编写了 docstring(官方库通常会写)。若某方法显示「⚠️ 无官方文档」,可能是库未提供该方法的说明,比如说上面某些方法,一些小众领域的库,开发者就是直接全代码无注释,提取不出来什么。
  3. 特殊成员过滤:代码中排除了以 __ 开头的内置成员(如 __init____str__),若需查看这些特殊方法,可删除 if not name.startswith("__") 的过滤条件。

拓展:将结果保存到文件

若输出内容过多,可将结果保存到 txt 文件,方便后续查阅:

# 在 print_all_methods_with_docs 函数中,添加文件写入逻辑
def print_all_methods_with_docs(library, save_to_file: bool = True) -> None:
    output_content = []  # 用列表存储所有内容,最后统一写入
    output_content.append(f"=== {library.__name__} 库方法及文档 ===")
    output_content.append(f"库路径: {library.__file__}\n")

    # 后续遍历成员时,将原本 print 的内容 append 到 output_content
    # 示例:
    # output_content.append(f"🔧 顶层函数: {member_name}")
    # output_content.append(get_object_doc(member, member_name))

    # 最后打印并保存
    final_content = "\n".join(output_content)
    print(final_content)
    
    if save_to_file:
        with open(f"{library.__name__}_docs.txt", "w", encoding="utf-8") as f:
            f.write(final_content)
        print(f"\n✅ 文档已保存到: {library.__name__}_docs.txt")
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值