Python带不同参数的工厂函数问题:适配类型检查需求
解决类型检查器识别工厂函数参数的方案
你的核心问题是默认字典类型无法让类型检查器区分不同变体对应的工厂函数签名,导致无法自动校验参数。下面提供两种可行的解决方式:
方案一:给工厂字典添加精确类型标注
通过typing模块的Literal和Callable,明确指定每个键对应的函数签名,让类型检查器能精准识别参数要求。
改进后的代码
from typing import Literal, Callable class Something: def __init__(self, one: int, two: int, three: int): self.one = one self.two = two self.three = three def create_one(one: int) -> Something: return Something(one=one, two=0, three=0) def create_two(one: int, two: int) -> Something: return Something(one=one, two=two, three=0) def create_three(one: int, two: int, three: int) -> Something: return Something(one=one, two=two, three=three) # 精确定义工厂字典的类型:每个字面量键对应特定签名的函数 FactoryType = dict[ Literal["one"], Callable[[int], Something], Literal["two"], Callable[[int, int], Something], Literal["three"], Callable[[int, int, int], Something], ] factory: FactoryType = { "one": create_one, "two": create_two, "three": create_three } # 类型检查器会提示需要传入1个参数 myfunc1 = factory["one"] variation_one = myfunc1(10) # 类型检查器会提示需要传入3个参数 myfunc3 = factory["three"] variation_three = myfunc3(10, 20, 30) # 参数数量错误时,类型检查器会直接报错 # variation_one = myfunc1() # 报错:缺少位置参数 # variation_three = myfunc3(10) # 报错:缺少2个位置参数
方案二:使用函数重载(@overload)
如果偏好通过单一函数分发不同变体,可以用@overload定义不同场景下的调用签名,让类型检查器根据变体参数自动匹配要求。
改进后的代码
from typing import overload, Literal class Something: def __init__(self, one: int, two: int, three: int): self.one = one self.two = two self.three = three # 给不同变体定义对应的重载签名 @overload def create_something(variation: Literal["one"], one: int) -> Something: ... @overload def create_something(variation: Literal["two"], one: int, two: int) -> Something: ... @overload def create_something(variation: Literal["three"], one: int, two: int, three: int) -> Something: ... # 实际实现逻辑 def create_something(variation: str, *args: int) -> Something: if variation == "one": return Something(one=args[0], two=0, three=0) elif variation == "two": return Something(one=args[0], two=args[1], three=0) elif variation == "three": return Something(one=args[0], two=args[1], three=args[2]) else: raise ValueError(f"未知变体类型: {variation}") # 类型检查器会自动匹配对应参数要求 variation_one = create_something("one", 10) variation_two = create_something("two", 10, 20) variation_three = create_something("three", 10, 20, 30) # 参数错误时类型检查器会报错 # create_something("one") # 报错:缺少one参数 # create_something("three", 10, 20) # 报错:缺少three参数
方案优势
这两种方式都避免了用默认值带来的参数歧义,其他开发者不需要查看函数内部实现,仅通过类型提示就能明确知道需要传入哪些参数,同时类型检查器会在编码阶段就拦截参数错误。
内容的提问来源于stack exchange,提问作者Alex K.
相关产品推荐
相关产品推荐

