(十七)用 argparse 接收启动参数
1. 启动参数与运行中的输入
第二章的程序启动后才通过 input() 等数据。现在希望在启动命令里直接写出数据和目标:python report.py 20 35 45 --goal 40。这些词由终端交给程序,argparse 负责按规则解析。
下面的文件放在 cli_demo 中:
# 项目文件:cli_demo/report.py
# ArgumentParser 创建解析器对象,add_argument 为它登记参数规则。
import argparse
def main():
parser = argparse.ArgumentParser(description="统计阅读分钟数")
parser.add_argument("minutes", nargs="*", type=int, help="每天的分钟数")
parser.add_argument("--goal", type=int, default=30, help="达标分钟数")
args = parser.parse_args()
# parse_args 返回保存结果的 Namespace,通过属性读取解析后的值。
print(args.minutes)
print("目标", args.goal)
print("达标天数", sum(value >= args.goal for value in args.minutes))
if __name__ == "__main__":
main()# 在 cli_demo 文件夹运行;末尾的参数会由 argparse 读取。
python report.py 20 35 45 --goal 40
# 解析器根据登记的规则生成帮助,并在显示后退出。
python report.py --help
第一条命令输出 [20, 35, 45]、“目标 40”“达标天数 1”。minutes 是位置参数,nargs="*" 收集零项或多项,type=int 在解析时实际调用 int 做转换;--goal 是带值的选项,省略后使用 30。
启动命令中的 --goal 与定义中的 goal=30 分属两层:前者先解析文本,后者是调用 Python 函数时绑定实参。argparse 不会因为函数有某个默认值,就自动创建同名命令行选项。
2. 开关与错误反馈
登记 parser.add_argument("--only-met", action="store_true"),表示出现该选项时保存 True,省略时为 False。读取结果的属性名是 args.only_met,选项名中的连字符会转换为下划线。下一节把这个开关接到筛选函数。
输入 python report.py 20 很多,int 转换失败后,解析器会显示用法和错误;python report.py --goal 缺少值时,也会指出对应选项。项目自己的数据规则可以在解析后检查,再调用 parser.error("具体原因") 显示错误并结束程序。这让启动参数的处理集中在入口,计算函数继续接收已经转换的数据。argparse 文档