如何在同一Python模块内反射获取并调用函数?
同一模块内反射调用函数及存在性判断方案
1. 解决getattr参数问题
在同一模块中,你可以通过两种方式获取当前模块的命名空间,作为getattr的第一个参数:
方式一:使用当前模块对象
通过sys.modules[__name__]获取当前模块的对象,直接传入getattr:
import sys # 先定义函数,确保解释器执行到调用时函数已存在 def foo_1(x): return x*x current_module = sys.modules[__name__] a = getattr(current_module, 'foo_1') b = a(5) print(b) # 输出25
方式二:使用全局命名空间字典globals()
globals()返回当前模块的全局变量字典,可直接通过键获取函数,或配合getattr使用:
def foo_1(x): return x*x # 直接用字典get方法,不存在时返回None a = globals().get('foo_1') if a: b = a(5) print(b) # 输出25
2. 判断函数是否存在的最佳方法
为避免因函数不存在抛出AttributeError,推荐两种安全方案:
方案一:用
getattr的默认参数
给getattr传入第三个参数(默认值),函数不存在时返回该值:import sys current_module = sys.modules[__name__] # 若foo_1不存在,a会是None a = getattr(current_module, 'foo_1', None) if a is not None and callable(a): b = a(5)方案二:检查键是否在
globals()中并验证类型
先判断函数名是否在全局命名空间,再确认对象是函数类型(避免和同名变量混淆):if 'foo_1' in globals() and callable(globals()['foo_1']): a = globals()['foo_1'] b = a(5)
3. 批量处理foo_<n>风格的函数
如果要批量找出所有符合foo_<n>命名规则的函数并调用,可以遍历模块的命名空间,筛选并验证类型:
import sys import types def foo_1(x): return x*x def foo_2(x): return x + 10 foo_3 = "这是一个变量,不是函数" current_module = sys.modules[__name__] # 筛选所有以foo_开头的函数 foo_functions = [ obj for name, obj in current_module.__dict__.items() if name.startswith('foo_') and isinstance(obj, types.FunctionType) ] # 批量调用函数 for func in foo_functions: print(func(5)) # 输出25、15
注意:函数定义必须在反射调用之前,因为Python是解释型语言,执行到调用代码时,函数必须已经被定义并加入到模块命名空间中。
内容的提问来源于stack exchange,提问作者Richard Pawson
相关产品推荐
相关产品推荐

