如何在Python中动态创建带注解与默认值的函数
Python运行时动态生成带类型注解与默认参数的函数
要实现一个函数工厂func_fact,根据给定的注解字典和默认参数字典生成签名匹配的函数,可以通过动态生成代码并执行的方式实现,具体方案如下:
实现代码
from typing import Tuple, Any import inspect def func_fact(annotations: dict[str, Any], defaults: dict[str, Any]) -> callable: # 构建参数列表字符串,格式为 "参数名: 类型注解 = 默认值" param_list = [] for param_name in annotations: # 处理类型注解的字符串表示 anno = annotations[param_name] if anno is Tuple[int]: # 特殊处理Tuple[int]这类泛型类型的字符串 anno_str = "Tuple[int]" else: anno_str = anno.__name__ if hasattr(anno, '__name__') else repr(anno) # 处理默认值的字符串表示 default_val = defaults[param_name] default_str = repr(default_val) param_list.append(f"{param_name}: {anno_str} = {default_str}") # 拼接参数成字符串 params_str = ", ".join(param_list) # 生成动态函数的代码字符串 func_def = f""" def dynamic_func({params_str}): # 这里可以替换为你需要的函数逻辑 return locals() """ # 执行代码生成函数 namespace = {} exec(func_def, globals(), namespace) generated_func = namespace['dynamic_func'] # 显式同步注解(exec生成的函数已自动包含,但确保完全匹配) generated_func.__annotations__ = annotations.copy() return generated_func
测试验证
# 定义输入的注解与默认参数 annotations = {'x': str, 'y': Tuple[int]} defaults = {'x': "some string", 'y': (1,2,3)} # 生成目标函数 f = func_fact(annotations, defaults) # 查看函数签名 print(inspect.signature(f)) # 输出:(x: str = 'some string', y: Tuple[int] = (1, 2, 3)) # 测试函数调用 print(f()) # 输出:{'x': 'some string', 'y': (1, 2, 3)} print(f(x="custom str", y=(4,5,6))) # 输出:{'x': 'custom str', 'y': (4, 5, 6)}
注意事项
- 类型注解兼容性:如果需要处理更复杂的泛型类型(如
List[Dict[str, int]]),可以扩展注解字符串的生成逻辑,比如使用typing.get_type_hints或inspect.formatannotation来获取更准确的类型字符串表示。 - 参数顺序:Python 3.7及以上版本的字典默认保持插入顺序,若需兼容旧版本,建议使用
collections.OrderedDict来传递annotations和defaults,确保参数顺序与预期一致。 - 函数逻辑自定义:示例中函数返回
locals(),你可以根据需求替换为任意业务逻辑,比如调用其他函数、计算结果等。
内容的提问来源于stack exchange,提问作者Loic Rosnay
相关产品推荐
相关产品推荐

