Python如何遍历指定目录下py文件并提取文件内定义的所有函数
实现方法
你可以根据自己的使用场景选下面两种方案,都不需要硬编码函数列表,新增文件后会自动收录:
方案1:动态导入模块收集(返回可直接调用的函数对象)
这个是最贴合你需求的方案,返回的列表里就是真实的函数对象,拿到就能直接调用,适合做API路由、统一调度的场景。
核心逻辑是遍历目录下的py文件,用importlib动态加载每个模块,再用inspect筛选出模块自身定义的顶层函数,自动过滤掉模块里import进来的外部依赖函数。
import inspect import importlib.util from pathlib import Path def collect_all_api_funcs(api_dir: str = "dir"): func_list = [] target_dir = Path(api_dir).resolve() # 遍历目录下所有.py文件 for py_file in target_dir.glob("*.py"): # 跳过__init__.py、私有工具文件这类以下划线开头的文件 if py_file.name.startswith("_"): continue # 动态加载单个py文件为模块 module_name = py_file.stem spec = importlib.util.spec_from_file_location(module_name, py_file) cur_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(cur_module) # 筛选当前模块自己定义的公开函数 for func_name, func_obj in inspect.getmembers(cur_module, inspect.isfunction): # 排除导入的外部函数、私有函数 if func_obj.__module__ == module_name and not func_name.startswith("_"): func_list.append(func_obj) return func_list
调用这个函数拿到的结果就是你要的[function1, function2, ...]格式,直接遍历就能用,比如:
all_funcs = collect_all_api_funcs() # 打印所有可用函数名 for f in all_funcs: print(f"可用函数:{f.__name__}") # 直接调用对应函数 # all_funcs[0]()
方案2:AST静态扫描(无代码执行副作用)
如果你的单个函数文件里有顶层执行的逻辑(比如导入时就触发连接数据库、跑测试代码),不想在收集函数的时候执行这些逻辑,可以用Python内置的ast模块静态解析源码,不需要导入文件就能拿到函数名。
缺点是这个方案只能拿到函数的名字符串,拿不到可直接调用的函数对象:
import ast from pathlib import Path def collect_all_api_func_names(api_dir: str = "dir"): func_name_list = [] target_dir = Path(api_dir).resolve() for py_file in target_dir.glob("*.py"): if py_file.name.startswith("_"): continue # 读取源码解析成语法树 with open(py_file, "r", encoding="utf-8") as f: syntax_tree = ast.parse(f.read()) # 提取所有顶层公开函数 for node in ast.walk(syntax_tree): if isinstance(node, ast.FunctionDef) and not node.name.startswith("_"): func_name_list.append(node.name) return func_name_list
注意事项
- 记得在
dir目录下新建一个空的__init__.py文件,把目录标记为Python合法包,避免动态导入时出现路径问题 - 两个方案都会自动识别后续新增的py文件,只要新文件放在dir目录下、公开函数定义在顶层,就会被自动收录,不需要修改收集逻辑
- 如果有不想被对外暴露的私有函数,给函数名或者文件名加下划线前缀,就会被自动过滤
内容的提问来源于stack exchange,提问作者Francis Godinho
相关产品推荐
相关产品推荐

