我的应用程序解析命令行参数:
import sys
import getopt
arguments = sys.argv[1:]
options, remainder = getopt.getopt(arguments, "aa:bb:cc:dd:h", ["aaaa=", "bbbb=", "cccc=", "dddd=", "help"])
print dict(options)
这很好但同时也很奇怪:如果我把参数放在不同的顺序中,它们就不会被解析
python my_app.py --aaaa=value1 --bbbb=value2 --cccc=value3 --dddd=value4 #ok
python my_app.py --dddd=value4 --bbbb=value2 --cccc=value3 --aaaa=value1 # empty
这令人失望,因为争论的顺序不重要,不应该吗?有什么方法可以解决这个问题吗?
更新:
python my_app.py -aa value1 # odd, empty { "-a" : "" }
python my_app.py -a value1 # even this empty { "-a" : "" }
答案 0 :(得分:1)
正如您对问题的第一条评论所述,关于以不同顺序解析参数失败的主要示例可以正常运行:
~/tmp/so$ python my_app.py --aaaa=value1 --bbbb=value2 --cccc=value3 --dddd=value4
{'--aaaa': 'value1', '--cccc': 'value3', '--dddd': 'value4', '--bbbb': 'value2'}
~/tmp/so$ python my_app.py --dddd=value4 --bbbb=value2 --cccc=value3 --aaaa=value1
{'--cccc': 'value3', '--bbbb': 'value2', '--aaaa': 'value1', '--dddd': 'value4'}
如果您不是这种情况,请更新脚本以打印剩余部分,并显示其输出。
但是,您仍然滥用getopt
库,这就是您提供的最新示例无法按预期工作的原因。您不能指定多个单个字符作为选项,因为第二个字符将被视为新的单独选项。 getopt
无法区分计为单个选项的两个连续字符(第一个不带参数值,因为它后面没有冒号)或单个选项由两个字符组成。来自getopt.getopt
's documentation,我更加强调:
options是脚本想要识别的选项字母的字符串,其中的选项需要参数后跟冒号。
因此,当getopt
解析您的参数时,每次遇到-a
参数时,它会将其与它注意到的第一个a
选项相关联,在您的情况下,它不会跟随一个冒号。因此,它设置此选项,丢弃其参数值,如果有任何(如果-aa
作为参数传递给脚本,第二个a
计为参数值)并转到下一个论点。
最后,关于getopt
和argparse
。 The documentation clearly advocates argparse
:
getopt模块是命令行选项的解析器,其API设计为C getopt()函数的用户熟悉。不熟悉C getopt()函数或想要编写更少代码并获得更好帮助和错误消息的用户应该考虑使用argparse模块。
有关argparse
优于getopt
和optparse
的原因的更多信息,请参阅this PEP和this question的答案。
getopt
中argparse
所支持的唯一功能虽然需要gnu getopt
中的一些工作,但与argparse
的参数顺序排列相似。但是,this question解释了如何通过{{1}}实现这一目标。