如何使用 Python 的 argparse 模块实现以下目标?:scale_data.py [-h] (-t | -r [倒数天数]| -i [开始日期])

How To Use Python's argparse module to achieve the following?: scale_data.py [-h] (-t | -r [Number of Days Back]| -i [Start Date])

我正在尝试使用 Python 的 argparse 模块。我的名为 scale_data.py 的 Python 脚本将需要使用 3 个可能的互斥开关中的 1 个:

scale_data.py -t

scale_data.py -r

scale_data.py -i

我已经想出如何使用“add_mutually_exclusive_group”实现这一点。我的问题是我希望 -r 开关或 -i 开关在它们之后有可选参数:

scale_data.py -r 20

scale_data.py -i 02/01/2021

但参数不是必需的。

我假设的帮助看起来是这样的:

scale_data.py [-h] (-t | -r [Number of Days Back]| -i [Start Date])

这是如何使用 Python argparse 模块完成的?

感谢您的帮助!

  1. 将您的选项添加到互斥组。
  2. nargs 设置为 "?" 以允许零个或一个参数。
  3. 将可选参数选项的 default 值设置为不是 None 的值;我只是在下面构造一个独特的哨兵对象。这显然是互斥检查与 "?" nargs 一起工作所必需的。
import argparse

NOTSET = object()


def main(argv):
    ap = argparse.ArgumentParser()
    ag = ap.add_mutually_exclusive_group()
    ag.add_argument("-t", action="store_true")
    ag.add_argument("-r", nargs="?", default=NOTSET)
    ag.add_argument("-i", nargs="?", default=NOTSET)
    print(ap.parse_args(argv))


if __name__ == '__main__':
    main(["-t"])
    main(["-r", "23"])
    main(["-i"])
    main(["-i", "8"])
    main(["-t", "-i", "8"])

这会打印出来

Namespace(t=True, r=<object>, i=<object>)
Namespace(t=False, r='23', i=<object>)
Namespace(t=False, r=<object>, i=None)
Namespace(t=False, r=<object>, i='8')

最后一个

error: argument -i: not allowed with argument -t

最后一次测试调用。

这是我最终使用@AKX 的答案创建的最终代码...

#!/usr/bin/python3

import argparse


def main():
    scale_data_parser = argparse.ArgumentParser(description='Get Withings Scale Data, Process Data, Populate DB, Generate Graphs and Reports.')
    mutually_exclusive_group = scale_data_parser.add_mutually_exclusive_group(required=True)
    mutually_exclusive_group.add_argument('-t', action='store_true', help='Fetch recent records then wait for trigger')
    mutually_exclusive_group.add_argument('-r', nargs='?', default=False, dest='Number Of Days Back', help='Fetch recent records then refresh all ouputs [Number Of Recent Days To Output (Int)]')
    mutually_exclusive_group.add_argument('-i', nargs='?', default=False, dest='Start Date', help='Fetech all records and completely reinitialize the database to the latest date as Start Date [Use This Start Date Instead (Date MM/DD/YYYY)]')
    scale_data_arguments = vars(scale_data_parser.parse_args())
    if scale_data_arguments['t']:
        print('(-t) Switch With No Arguments')
    elif scale_data_arguments['Number Of Days Back'] is None:
        print('(-r) Switch With No Arguments')
    elif scale_data_arguments['Number Of Days Back'] is not None and scale_data_arguments['Number Of Days Back'] is not False:
        print(f'(-r) Switch With An Argument ({scale_data_arguments["Number Of Days Back"]})')
    elif scale_data_arguments['Start Date'] is None:
        print('(-i) Switch With No Arguments')
    elif scale_data_arguments['Start Date'] is not None and scale_data_arguments['Start Date'] is not False:
        print(f'(-i) Switch With An Argument ({scale_data_arguments["Start Date"]})')


if __name__ == '__main__':
    main()