Python 当一个选项放在其余位置参数之前时,为什么argparse会失败?
考虑使用python 3.7.2在scratch.py中的这个测试argparse示例:Python 当一个选项放在其余位置参数之前时,为什么argparse会失败?,python,argparse,Python,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.ad
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
为什么第四个案例失败了?
hello john --sound bell loud red
解析为:
greeting = 'hello'
name = 'john'
params = []
sound = 'bell'
['loud'、'red']
是剩余的
解析器也可以处理位置和可选属性。它使用正则表达式样式的模式匹配将位置集分配给下一个可选('--sound')。'“问候语”和“姓名”都需要一个字符串。”params'可以接受任何列表('*'),包括空列表。一旦用完了,就没有更多的参数可以使用“loud”和“red”
这是一种狡猾的行为,并不理想。在这个主题上至少有一个bug/问题,但是如果我的记忆是正确的,那就不是一件容易修补的事情
更改为nargs='+'
应给出正确的解析。此答案基于的响应
这是argparse中的一个错误,但有一个解决方法:将parse_args
替换为parse_mixed_args
这适用于问题中的示例(以及实际应用程序,该应用程序具有许多子命令和不同的标志和位置参数)但是如果使用
argparse.rements
之类的东西,它可能会失败。更改nargs='+'
确实正确地解析了第四个示例,但这是一个不正确的规范,因为python scratch.py hello john--sound bell
现在失败了。params的目的是它可以包含零个或多个参数。您是否有该错误/问题的链接?另一个选项是将其更改为“--parms”;使用标志可以提供更多的控制。或parse_known_args
收集所有“剩余”字符串。谢谢,parse_mixed_args给出了正确答案。但真正的应用程序使用的是水泥,因此我必须深入研究,看看是否可以在不出现其他问题的情况下更改它。我忘记了混合
。这将期权和头寸的处理分离开来。它的本意是允许拆分*位置,但作为一个副作用,它会清除此行为。旧的optpass处理可选项,并将其他所有项都放在附加项列表中。