如何简化支持多参数类型的Callable的Mypy类型注解?
解决Callable类型兼容问题的优化方案
方法一:用TypeVar批量定义允许的输入类型
先定义一个涵盖所有合法输入的TypeVar,再让baz的参数指向接受该TypeVar的Callable,不用手动写冗长的Union:
from typing import TypeVar, Callable, Sequence, Any class Foo: pass class Bar: pass # 把所有允许的输入类型列在这里,后续加新类型直接补充 InputType = TypeVar('InputType', Foo, Bar, Sequence[Foo]) def baz(func: Callable[[InputType], Any]) -> None: # 编写你的函数逻辑 pass # 测试用例均可通过Mypy检查 def handle_single_foo(f: Foo) -> Any: return None def handle_single_bar(b: Bar) -> Any: return None def handle_foo_sequence(s: Sequence[Foo]) -> Any: return None baz(handle_single_foo) baz(handle_single_bar) baz(handle_foo_sequence)
后续要新增输入类型(比如Baz或Sequence[Bar]),只需要在TypeVar的参数里追加,不用修改baz的类型注解。
方法二:用Protocol定义兼容的调用签名
如果需要更灵活的签名匹配(比如未来要支持多参数场景),可以用Protocol明确所有允许的调用格式:
from typing import Protocol, Callable, Sequence, Any class Foo: pass class Bar: pass class Handler(Protocol): def __call__(self, arg: Foo) -> Any: ... def __call__(self, arg: Bar) -> Any: ... def __call__(self, arg: Sequence[Foo]) -> Any: ... def baz(func: Handler) -> None: # 编写你的函数逻辑 pass
这种方式的优势是可以精细化定义每个合法的调用签名,哪怕不同签名的参数数量或返回类型有差异,也能准确匹配。
内容的提问来源于stack exchange,提问作者natty
相关产品推荐
相关产品推荐

