Python函数含命名与可变关键字参数时mypy类型检查报错问题
问题
我定义了一个同时包含命名参数与可变关键字参数的函数:
def safe_format(text: str, max_errors: int = 10, **kwargs: str) -> None: print(text) print(max_errors) print(kwargs)
当省略max_errors参数调用该函数时:
safe_format(some_str, **some_dict)
程序运行符合预期(依次打印some_str、10、some_dict),但mypy报错:
Argument 2 to "safe_format" has incompatible type "**Dict[str, str]"; expected "int"
请问是否有特定语法可以让mypy正确识别我的调用逻辑?
解决方法
有几种方式可以解决这个mypy类型检查问题:
1. 显式指定max_errors参数(推荐)
调用时明确传入max_errors的默认值,让mypy清晰区分位置参数和关键字参数:
safe_format(some_str, max_errors=10, **some_dict)
这种方式不需要修改函数定义,代码可读性更强,同时能让mypy准确识别参数传递逻辑。
2. 调整函数参数顺序
修改函数定义,将**kwargs放在max_errors之前,这样max_errors必须以关键字参数形式传递:
def safe_format(text: str, **kwargs: str, max_errors: int = 10) -> None: print(text) print(max_errors) print(kwargs)
此时调用可以正常使用safe_format(some_str, **some_dict),mypy不会报错;如果需要自定义max_errors,则必须写成safe_format(some_str, max_errors=5, **some_dict)。不过这种方式会改变函数的调用约定,需要评估是否影响现有代码。
3. 使用Python 3.11+的typing.Unpack
在Python 3.11及以上版本,结合新版mypy,可以用Unpack标注字典类型,明确告知mypy该字典是作为关键字参数展开:
from typing import Unpack, Dict def safe_format(text: str, max_errors: int = 10, **kwargs: str) -> None: print(text) print(max_errors) print(kwargs) # 定义字典时指定类型 some_dict: Dict[str, str] = {"key": "value"} safe_format(some_str, **some_dict)
这种方式不需要修改函数调用逻辑,但依赖较高版本的Python和mypy。
内容的提问来源于stack exchange,提问作者totooooo
相关产品推荐
相关产品推荐

