如何为可接受任意字符串参数与关键字参数的函数标注类型?
正确标注符合要求的函数类型
要让mypy正确识别你需要的函数类型,不能直接用Callable[[str, ...], str]——这个标注允许后续位置参数是任意类型,不符合你“所有位置参数必须是str”的要求,也没明确关键字参数的规则。正确的做法是用Protocol来定义精确的调用签名:
步骤1:定义调用协议
通过typing.Protocol创建一个协议类,严格限定函数的参数和返回值规则:
from typing import Protocol, Any class ValidFunc(Protocol): def __call__(self, *args: str, **kwargs: Any) -> str: ...
这个协议规定:
- 函数可以接受任意数量的
str类型位置参数(*args: str) - 函数可以接受任意数量、任意类型的关键字参数(
**kwargs: Any) - 函数必须返回
str类型
步骤2:使用协议标注函数
把这个协议作为类型注解,标注你要接受的函数参数:
def process_func(func: ValidFunc) -> ValidFunc: def wrapper(*args: str, **kwargs: Any) -> str: # 这里可以添加你的逻辑 return func(*args, **kwargs) return wrapper
验证示例
符合要求的函数(mypy会通过)
@process_func def func1(a: str, b: str, c: str, *, foo: int) -> str: return f"{a}{b}{c}{foo}" @process_func def func2(a: str, b: str, *, foo: int) -> str: return f"{a}{b}{foo}" @process_func def func3(a: str) -> str: return a
不符合要求的函数(mypy会报错)
# 错误:位置参数`foo`是int类型,违反了所有位置参数必须为str的规则 @process_func def bad_func1(a: str, b: str, c: str, foo: int) -> str: return f"{a}{b}{c}{foo}" # 错误:第一个参数是int类型,不是str @process_func def bad_func2(foo: int) -> str: return str(foo)
为什么之前的Callable不行?
Callable[[str, ...], str]的含义是“接受至少一个str位置参数,后续可以跟任意类型的位置参数”,这和你要求的“所有位置参数必须是str”不符。而Protocol的方式可以精确描述调用签名的每一部分,让mypy能准确校验。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

