如何在Python中提取不含签名的函数体?
提取Python函数的源码体(不含签名)
使用inspect.getsource()可以获取函数的完整源码,但默认输出包含函数签名。如果函数签名是多行形式,仅跳过第一行的方法并不可靠,这里提供一种基于AST语法解析的健壮方案:
实现代码
import inspect import ast def get_function_body(func): # 获取目标函数的完整源码 source_code = inspect.getsource(func) # 将源码解析为抽象语法树(AST) ast_tree = ast.parse(source_code) # 从AST中取出函数定义节点 func_def_node = ast_tree.body[0] # 获取函数体第一个语句的行号(AST行号从1开始计数) body_start_line = func_def_node.body[0].lineno # 按行分割源码,提取函数体部分 source_lines = source_code.splitlines() body_lines = source_lines[body_start_line - 1:] # 拼接并返回函数体源码 return '\n'.join(body_lines) # 测试用例 def main(): # 单行签名函数 def example_function(): x = 4 y = 3 if x + y < 6: print("Test") print("Example") # 多行签名函数 def multi_param_func(a, b: int, c="default") -> str: """带多行签名和类型注解的函数""" result = a + b + len(c) print(f"计算结果:{result}") return str(result) # 输出测试结果 print("单行签名函数的函数体:") print(get_function_body(example_function)) print("\n多行签名函数的函数体:") print(get_function_body(multi_param_func)) if __name__ == "__main__": main()
方案优势
- 精准定位:通过AST解析能准确识别函数体的起始位置,不管函数签名是单行、多行,还是带有类型注解、默认参数,都能正确分割。
- 健壮性高:避免了通过字符串匹配或行数判断带来的误判,完全基于Python语法结构分析。
注意事项
- 该方法仅适用于通过
def关键字定义的函数,不适用于lambda表达式(lambda本身没有独立的函数体结构)。 - 确保目标函数的源码是可获取的(比如不是内置函数、不是动态生成的无源码函数)。
内容的提问来源于stack exchange,提问作者ideasman42
相关产品推荐
相关产品推荐

