You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python AST提取类、类内函数及函数调用?求示例代码

用AST提取Python代码中的类、方法及内部函数调用示例

我明白你想用AST提取Python代码里的类、类中的方法,还有每个方法内部调用的函数——之前的代码只遍历了所有ast.Name节点,确实没法精准区分这些元素。下面是一个能满足你需求的完整示例代码,还会附带详细的解释:

完整示例代码

import ast
from typing import Dict, List

def analyze_python_code(file_path: str) -> Dict[str, Dict[str, List[str]]]:
    """
    分析Python文件,提取类、类中的方法,以及每个方法内部调用的函数
    返回结构: {类名: {方法名: [调用的函数列表]}}
    """
    with open(file_path, 'r', encoding='utf-8') as f:
        code = f.read()
    
    tree = ast.parse(code, filename=file_path)
    result = {}

    # 遍历所有类节点
    for node in ast.walk(tree):
        if isinstance(node, ast.ClassDef):
            class_name = node.name
            result[class_name] = {}
            
            # 遍历类下的所有方法/函数
            for item in node.body:
                if isinstance(item, ast.FunctionDef):
                    func_name = item.name
                    called_funcs = []
                    
                    # 遍历函数内部的所有调用节点
                    for sub_node in ast.walk(item):
                        if isinstance(sub_node, ast.Call):
                            # 处理直接调用的函数(比如 func())
                            if isinstance(sub_node.func, ast.Name):
                                called_funcs.append(sub_node.func.id)
                            # 处理属性调用(比如 obj.method())
                            elif isinstance(sub_node.func, ast.Attribute):
                                called_funcs.append(f"{sub_node.func.value.id}.{sub_node.func.attr}")
                    
                    result[class_name][func_name] = called_funcs
    
    return result

# 使用示例
if __name__ == "__main__":
    analysis_result = analyze_python_code("test.py")
    for class_name, methods in analysis_result.items():
        print(f"* 类: {class_name}")
        for method_name, called_funcs in methods.items():
            print(f"  - 方法: {method_name}")
            if called_funcs:
                print(f"    调用的函数: {', '.join(called_funcs)}")
            else:
                print(f"    未调用任何函数")

代码关键逻辑说明

  • 文件解析与AST生成:用with语句安全读取文件,避免资源泄漏;通过ast.parse()将代码字符串转换为AST语法树,指定filename参数能让报错信息更准确。
  • 提取类节点:筛选ast.ClassDef类型的节点,获取类的名称(node.name)。
  • 提取类中的方法:在类节点的body属性中,筛选ast.FunctionDef节点,这些就是类的方法(包括普通方法、类方法、静态方法,如需区分可进一步判断decorator_list属性)。
  • 提取方法内部的函数调用:在方法节点内部遍历ast.Call节点,区分两种常见调用场景:
    • 直接调用普通函数(如print()):对应ast.Name类型的func属性,提取id即为函数名。
    • 属性调用(如self.get_data()requests.get()):对应ast.Attribute类型的func属性,拼接value.id(对象/模块名)和attr(方法名)得到完整调用路径。
  • 返回结构化结果:用嵌套字典存储数据,方便后续的遍历、输出或进一步处理。

小技巧:探索AST节点结构

如果觉得官方文档不够清晰,你可以在遍历节点时打印节点的属性字典,快速了解节点包含的信息:

for node in ast.walk(tree):
    if isinstance(node, ast.Call):
        print(vars(node))  # 打印节点的所有属性和值

内容的提问来源于stack exchange,提问作者Coder

火山引擎 最新活动