遍历目录提取Python文件函数名,寻求更Pythonic的实现方式
嘿,这个问题问得好!用正则匹配函数名虽然能完成基础需求,但Python其实有更优雅、更可靠的方式来做这件事——毕竟正则很容易漏掉一些边缘情况(比如跨多行的函数定义、带装饰器的函数,甚至是被注释掉的def行)。下面给你几个更符合Python风格的实现思路:
方法一:利用ast模块(最可靠的首选方案)
Python自带的ast(抽象语法树)模块可以直接解析代码的语法结构,能精准识别所有合法的函数定义,完全不会被代码格式干扰,这绝对是最Pythonic的做法。
import ast import os # 先检查folder2是否存在,用脚本所在目录拼接路径更健壮 target_dir = os.path.join(os.path.dirname(__file__), "folder2") if not os.path.isdir(target_dir): print("folder2不存在") exit() # 遍历folder2下所有.py文件 for filename in os.listdir(target_dir): if filename.endswith(".py"): file_path = os.path.join(target_dir, filename) with open(file_path, "r", encoding="utf-8") as f: # 把代码解析成抽象语法树 tree = ast.parse(f.read()) # 遍历语法树节点,筛选函数定义 for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): print(node.name)
这个方法能完美处理各种复杂情况:带装饰器的函数、跨多行定义的函数、嵌套函数……只要是合法的Python函数,它都能准确提取名字。
方法二:优化正则写法(简单场景的折中方案)
如果你觉得ast有点“重”,想继续用正则,也可以优化写法,让它更严谨、更高效:
import re import os target_dir = os.path.join(os.path.dirname(__file__), "folder2") if not os.path.isdir(target_dir): print("folder2不存在") exit() # 预编译正则表达式,提升重复匹配的效率 func_pattern = re.compile(r'^\s*def\s+(\w+)\s*\(') for filename in os.listdir(target_dir): if filename.endswith(".py"): file_path = os.path.join(target_dir, filename) with open(file_path, "r", encoding="utf-8") as f: for line in f: match = func_pattern.match(line) if match: print(match.group(1))
这里做了几个优化:
- 预编译正则,避免重复编译带来的性能损耗
- 匹配行首的空白字符,兼容不同缩进的函数定义
- 用
\w+精准匹配函数名(只允许字母、数字、下划线) - 只调用一次
match,避免原代码里的重复正则调用
额外小提示:路径处理要健壮
原代码里用了硬编码的路径"folder1/folder2/hello_world.py",这很容易出问题(比如运行脚本时的工作目录变化)。用os.path.dirname(__file__)获取当前脚本所在的目录,再拼接子目录,不管脚本从哪里运行都能正确找到目标文件。
总结一下,优先推荐ast模块,它是Python官方提供的代码解析工具,完全符合Pythonic的“用正确的工具做正确的事”理念;如果是非常简单的场景,优化后的正则也能凑合用,但可靠性远不如ast。
内容的提问来源于stack exchange,提问作者Neal Mc Beal
相关产品推荐
相关产品推荐

