Python如何遍历、匹配并调用函数内部的嵌套子函数
Python嵌套子函数访问实现方案
问题说明
此前通过inspect.getmembers遍历模块成员的实现逻辑存在局限:
functions = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isfunction)]
该逻辑仅能返回指定模块下的顶层函数,无法识别函数内部定义的嵌套子函数,例如下方示例中f内部的y、z就无法被上述代码捕获:
def f(x): def y(x): x += 3 return x def z(x): return x**2 - 1 x += y(x) x += z(x) return x
注:原示例中return x += 3存在语法错误,已做修正。
嵌套子函数不会作为外层函数的公开属性存储,也不存在可以直接返回子函数列表的魔术方法,需要通过Python函数的代码对象属性提取。
实现原理
Python编译阶段会把函数内部定义的所有子函数编译为CodeType类型的代码对象,统一存放在外层函数__code__属性的co_consts常量元组中。遍历该元组筛选出代码类型的条目,再封装为可调用的函数对象,即可拿到所有直接嵌套的子函数。
完整实现代码
import inspect import types def get_nested_funcs(outer_func): """获取指定外层函数下所有直接嵌套的第一层子函数""" nested_list = [] for const_item in outer_func.__code__.co_consts: if isinstance(const_item, types.CodeType): # 绑定外层函数的全局命名空间,生成可调用的函数对象 sub_func = types.FunctionType(const_item, outer_func.__globals__) nested_list.append(sub_func) return nested_list
按名称匹配调用子函数的逻辑和预期伪代码一致:
# 示例:查找f下名为y的子函数并传参调用 target_func_name = "y" call_params = (2,) for subfunc in get_nested_funcs(f): if subfunc.__name__ == target_func_name: result = subfunc(*call_params) print(result) # 输出5,对应y(2)的计算结果 break
注意事项
- 上述方法仅能获取直接嵌套在当前函数下的第一层子函数,如果需要获取多层嵌套的子函数,递归遍历每个子函数的
__code__.co_consts即可 - 提取出的子函数默认不携带外层函数运行时的闭包上下文,如果子函数引用了外层函数的局部变量,直接调用会抛出变量未定义错误,这类场景需要额外手动绑定闭包变量
- 该实现兼容所有Python 3.x版本,不需要依赖第三方库
内容的提问来源于stack exchange,提问作者Emerson
相关产品推荐
相关产品推荐

