首页 > 解决方案 > 为什么将选项放在其余位置参数之前时,argparse 会失败?

问题描述

考虑使用 python 3.7.2 在 scratch.py​​ 中的这个测试 argparse 示例:

import sys
import argparse
import yaml


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--sound', nargs='?', default=None)
    parser.add_argument('greeting')
    parser.add_argument('name')
    parser.add_argument('params', nargs='*')
    return vars(parser.parse_args(sys.argv[1:]))


def main():
    print(yaml.dump((get_args())))


if __name__ == "__main__":
    main()

如果我使用它:

(websosadmin) ~/wk/cliosoft/websosadmin/sosadmin_cli $ python scratch.py hello john loud red
greeting: hello
name: john
params:
- loud
- red
sound: null

(websosadmin) ~/wk/cliosoft/websosadmin/sosadmin_cli $ python scratch.py --sound bell hello john loud red
greeting: hello
name: john
params:
- loud
- red
sound: bell

(websosadmin) ~/wk/cliosoft/websosadmin/sosadmin_cli $ python scratch.py hello --sound bell john loud red
greeting: hello
name: john
params:
- loud
- red
sound: bell

(websosadmin) ~/wk/cliosoft/websosadmin/sosadmin_cli $ python scratch.py hello john --sound bell loud red
usage: scratch.py [-h] [--sound [SOUND]] greeting name [params [params ...]]
scratch.py: error: unrecognized arguments: loud red

为什么第四个案例会失败?

标签: pythonargparse

解决方案


这个答案建立在hpaulj的回应之上。

这是 argparse 中的一个错误,但有一个解决方法:替换parse_argsparse_intermixed_args.

这在问题的示例中有效(以及在具有许多子命令和不同标志和位置参数的复杂的实际应用程序中)但如果argparse.REMAINDER使用类似的东西可能会失败。


推荐阅读