Argparse, nargs with 1 required, 1 optional?



我希望为我的解析器提供灵活的输入。我的用例是我有一个python脚本来运行一些基于日期范围的查询。我希望arg解析器的操作方式是,如果只提供了一个日期,则使用该日期作为开始日期和结束日期,但如果使用了两个日期,则使用它们。

因此至少需要提供一个日期,但不超过两个日期。这可能吗?

def main(args):
parser = argparse.ArgumentParser(description="Run ETL for script")

parser.add_argument('-j', '--job_name', action='store', default=os.path.basename(__file__), type=str, help="Job name that gets used as part of the metadata for the job run.")
parser.add_argument("-d", "--date-range", nargs=2, metavar=('start_date', 'end_date'), default=['2021-01-01', '2021-01-01'], action='store', help="Operating range for script and data sources (as applicable)")
parser.add_argument('-e', '--env', action='store', choices=['dev', 'stage', 'prod'], default='dev', help="Environment to execute.")
parser.add_argument('-c', '--config', action='store', choices=['small', 'medium', 'large'], default='small', help="Resource request.  See configs for each.") 

args = parser.parse_args()

if args.date_range[0] <= args.date_range[1]:
job_meta = {
"script" : args.job_name,
"start_date" : args.date_range[0],
"end_date" : args.date_range[1],
"environment" : args.env,
"resource" : args.config
}
run_job(job_meta)
else:
print('Invalid date range.  Start date as inputted may be following the end date.')
sys.exit(0)
if __name__ == "__main__":
main(sys.argv[1:])

为了实现这一点,您可以创建一个新的操作来检查给nargs的参数数量。

import argparse
class LimitedAppend(argparse._AppendAction):
def __call__(self, parser, namespace, values, option_string=None):
if not (1 <= len(values) <= 2):
raise argparse.ArgumentError(self, "%s takes 1 or 2 values, %d given" % (option_string, len(values)))
super().__call__(parser, namespace, values, option_string)

parser.add_argument("-d", "--date-range", ..., nargs='+', action=LimitedAppend)

然后你可以检查这个参数的长度并做你想做的事情

最新更新