我正在尝试做一件非常简单的事情 - 只有两个选项:-p
和-c
,相互排斥,可能有也可能没有参数,带有可选参数的th...is
或没有一个th...at
。这就是我得到的:
def main():
import argparse
parser = argparse.ArgumentParser(description = '''ArgParser with optional argument''',
argument_default = argparse.SUPPRESS)
group1 = parser.add_mutually_exclusive_group(required=True)
group1.add_argument('-p', '--project', dest='proj',
nargs='?', const='all', type=str,
help='list of project(s)')
group1.add_argument('-c', '--component', dest='comp',
nargs='?', const='all', type=str,
help='list of Component(s)')
args = parser.parse_args()
print(args)
if args.proj:
outString = 'project/'+args.proj if args.proj is not 'all' else 'projects'
elif args.comp:
outString = 'component/'+args.comp if args.comp is not 'all' else 'components'
else: pass
print('OutPutString: '+outString)
if __name__ == "__main__":
import sys
try: sys.exit(main())
except KeyboardInterrupt: pass
finally: print
适用于if-elif-else
块中的第一个条件,因此可以正常工作:
dass@mon105:~$ ./argParseOpts.py -p
Namespace(proj='all')
OutPutString: projects
#
dass@mon105:~$ ./argParseOpts.py -p testing
Namespace(proj='testing')
OutPutString: project/testing
但不是-c
代替-p
(即第二个条件):
dass@mon105:~$ ./argParseOpts.py -c
Namespace(comp='all')
Traceback (most recent call last):
File "./argParseOpts.py", line 32, in <module>
try: sys.exit(main())
File "./argParseOpts.py", line 21, in main
if args.proj:
AttributeError: 'Namespace' object has no attribute 'proj'
任何人都可以告诉我,如果我遗失任何东西或做任何根本错误的事情吗?使用v2.7.2,如果重要的话。干杯!!
答案 0 :(得分:1)
由于您将argument_default
值设置为argparse.SUPPRESS
,因此未设置任何属性,这意味着除非属性具有显式值,否则永远不会设置属性。
Set可以为每个参数设置一个显式的default=None
值,以便为这些特定选项再次获取属性:
group1.add_argument('-p', '--project', dest='proj',
nargs='?', const='all', type=str,
help='list of project(s)', default=None)
group1.add_argument('-c', '--component', dest='comp',
nargs='?', const='all', type=str,
help='list of Component(s)', default=None)
将再次设置args.proj
和args.comp
属性。 None
是一个假值,因此if args.proj
测试不会传递到另一个分支,例如。
另一种方法是使用hasattr()
查看属性是否已设置:
if hasattr(args, 'proj'):
答案 1 :(得分:0)
由于已经使用Argparse回答了该问题,我建议您使用docopt作为替代方案。以标准格式编写界面帮助消息,这就是您需要做的所有事情。如果我理解你的使用方法就是这样。
在这种情况下解决问题的关键是制作-p
和-c
标记,并为字符串使用不同的变量NAME
。
"""Usage:
myprog (-p [NAME] | -c [NAME])
Options:
-p, --project list of project(s)
-c, --component list of component(s)
"""
from docopt import docopt
if __name__ == "__main__":
arguments = docopt(__doc__)
print(arguments)
name = 'all' if arguments['NAME'] is None else arguments['NAME']
if arguments['--project']:
...
elif arguments['--component']:
...
如果我们只打印参数,则使用模式将如下所示。
$ python myprog.py
Usage:
...
$ python myprog.py -p
{'--project': True,
'--component': False,
'NAME': None}
$ python myprog.py -c foo
{'--project': False,
'--component': True,
'NAME': 'foo'}
$ python myprog.py -p foo -c bar
Usage:
...
答案 2 :(得分:0)
错误原因是SUPPRESS
parser = argparse.ArgumentParser(description = '''ArgParser with optional argument''',
argument_default = argparse.SUPPRESS)
使用此选项,如果参数未显示在argv
中,则它不会显示在Namespace
中。
dass@mon105:~$ ./argParseOpts.py -c
Namespace(comp='all')
Traceback (most recent call last):
File "./argParseOpts.py", line 32, in <module>
try: sys.exit(main())
File "./argParseOpts.py", line 21, in main
if args.proj:
AttributeError: 'Namespace' object has no attribute 'proj'
当您提供-p
时,args.comp
会返回相同的错误(除了您先检查proj
)。
我喜欢在交互式shell中测试这样的问题(例如IPython
)。在那里,我可以输入您的parser
定义,并发出如下命令:
In [35]: parser.parse_args(['-p'])
Out[35]: Namespace(proj='all')
In [36]: parser.parse_args(['-c'])
Out[36]: Namespace(comp='all')
In [37]: parser.parse_args(['-c','test'])
Out[37]: Namespace(comp='test')
显而易见,只设置了一个属性。