Python如何在内存中动态创建带参数类型提示的函数?
更稳定的动态创建带类型提示函数的实现方案
现有基于exec的实现最大的问题是存在代码注入风险、动态变量名解析容易出异常,也不支持复杂函数逻辑的定义,推荐以下两种可控性更高的实现:
方案1:基于types.FunctionType手动修改函数属性(推荐大多数场景使用)
直接先写好固定的函数骨架,再动态修改函数名、类型注解等属性,完全规避动态代码执行风险:
import types import typing req_type = int func_name = "some_function_name" # 预定义函数骨架,内部可以写任意你需要的业务逻辑 def _dummy_template(my_argument): pass # 基于骨架生成新的函数实例 a = types.FunctionType( code=_dummy_template.__code__, globals=_dummy_template.__globals__, name=func_name, argdefs=_dummy_template.__defaults__, closure=_dummy_template.__closure__ ) # 显式设置类型注解 a.__annotations__ = {"my_argument": req_type}
验证效果和你现有实现完全一致:
print(a) # <function some_function_name at 0x...> print(typing.get_type_hints(a)) # {'my_argument': <class 'int'>}
方案2:动态构造函数签名(适用于参数数量/名称完全动态的场景)
如果连参数列表都需要运行时才能确定,可以用inspect模块动态构造参数签名,适配最灵活的需求:
import inspect import typing from inspect import Parameter, Signature req_type = int func_name = "some_function_name" # 通用函数逻辑,用可变参数接收所有入参 def _dynamic_impl(*args, **kwargs): # 这里写你的通用业务逻辑即可 return args[0] if args else None # 动态构造参数列表 params = [ Parameter( name="my_argument", kind=Parameter.POSITIONAL_OR_KEYWORD, annotation=req_type ) # 可以在这里加任意多的参数定义 ] # 给函数绑定签名、注解、自定义名称 _dynamic_impl.__signature__ = Signature(params) _dynamic_impl.__annotations__ = {p.name: p.annotation for p in params if p.annotation is not inspect._empty} _dynamic_impl.__name__ = func_name a = _dynamic_impl
内容的提问来源于stack exchange,提问作者M Leonard
相关产品推荐
相关产品推荐

