如何为argparse参数添加类型提示以支持mypy、PyFlakes、Pylint校验
问题根源
argparse.ArgumentParser.parse_args() 默认返回的是无固定属性定义的argparse.Namespace对象,所有属性都是运行时动态添加的,PyFlakes、Pylint、mypy这类静态检查工具无法在编码阶段推断属性是否存在、以及对应的类型,自然没法捕获你给出的示例里的类型不匹配错误。
可用改进方案
方案1:自定义继承自Namespace的带类型标注的类(无额外依赖,最轻便)
直接定义一个继承argparse.Namespace的类,给所有参数加上明确的类型标注,再将parse_args()的返回值显式标注为这个自定义类的类型,静态检查工具就可以正常识别属性和对应类型:
import argparse from argparse import Namespace # 自定义带类型的参数类 class Args(Namespace): float_input: float parser = argparse.ArgumentParser() parser.add_argument('--float_input', type=float) # 显式标注返回值类型 args: Args = parser.parse_args() def int_sum(a: int, b: int): return a + b # 此时mypy会直接报错:参数1的类型"float"无法赋值给类型"int" c = int_sum(args.float_input, args.float_input) # 如果打错属性名比如args.float_inpt,静态检查也会直接提示属性不存在
这个方案不需要安装任何第三方依赖,mypy、Pylint都可以正常识别。
方案2:使用Dataclass封装参数(可读性更高,适合参数多的场景)
如果参数较多,用dataclass来定义参数结构更清晰,之后手动把Namespace的属性赋值到dataclass实例即可:
import argparse from dataclasses import dataclass @dataclass class Args: float_input: float parser = argparse.ArgumentParser() parser.add_argument('--float_input', type=float) raw_args = parser.parse_args() args = Args(**vars(raw_args)) def int_sum(a: int, b: int): return a + b # 同样会触发类型错误提示 c = int_sum(args.float_input, args.float_input)
Python 3.7以上版本支持原生dataclass,不需要额外依赖,还可以方便地给参数加默认值、自定义校验逻辑。
方案3:使用支持类型的参数解析库
如果是新项目,可以直接用支持原生类型提示的参数解析库,不需要手动写add_argument和类型标注的重复逻辑,比如typer、pydantic-argparse这类库,定义完类型之后自动生成参数解析逻辑,静态检查天然支持。
内容的提问来源于stack exchange,提问作者rkamoi
相关产品推荐
相关产品推荐

