Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带可选参数的ArgumentParser(在互斥组中)_Python_Python 2.7_Arguments_Argparse - Fatal编程技术网

Python 带可选参数的ArgumentParser(在互斥组中)

Python 带可选参数的ArgumentParser(在互斥组中),python,python-2.7,arguments,argparse,Python,Python 2.7,Arguments,Argparse,我试着做一件非常简单的事情-只有两个选项:-p和-c,相互排斥,可能有参数,也可能没有参数,使用可选参数做th…is,或者不使用参数做th…at。这就是我得到的: def main(): import argparse parser = argparse.ArgumentParser(description = '''ArgParser with optional argument''', argumen

我试着做一件非常简单的事情-只有两个选项:
-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 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
名称空间(comp='all')
回溯(最近一次呼叫最后一次):
文件“/argParseOpts.py”,第32行,在
try:sys.exit(main())
文件“/argParseOpts.py”,第21行,主
如果args.proj:
AttributeError:“命名空间”对象没有属性“proj”

有谁能告诉我,我是否遗漏了什么或做了什么根本错误的事情?使用v2.7.2,如果有必要的话。干杯

没有设置属性,因为您将
参数\u 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'):

由于已经使用Argparse解决了这个问题,因此我建议使用Argparse作为替代方法。以标准格式编写界面帮助消息,这就是您所需要做的。如果我对你的用法理解正确的话,情况就是这样

在这种情况下,解决问题的关键是设置
-p
-c
标志,并为字符串使用不同的变量
名称

"""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:
...

错误的原因是
抑制

parser = argparse.ArgumentParser(description = '''ArgParser with optional argument''',
                                 argument_default = argparse.SUPPRESS)
使用此选项,如果参数未出现在
argv
中,则它不会出现在
命名空间中

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'

很明显,只有一个属性被设置。

@MartijnPieters:humm。。。。我在v2.7.3上也看到了同样的错误。试图找出我是否在任何地方安装了v2.7.5。但是在生产机器上,无论如何我必须使用V2.7.2。对不起,这是你在我测试你的问题的时候走开的时候得到的,然后忘了我把它放进去。P@MartijnPieters:只是在原始帖子中添加了
if uuuuuu name_uuuu==“uuuuu main_uuuuu”:
位,以确保不会导致此问题。Juts在v3.3.3上进行了测试,但仍然存在相同的错误。但是没有发现安装了v2.7.5的盒子。我认为,最初的版本仍然是一样的——它适用于第一种情况。在您的修复中,如果我切换
如果elif
阻塞,它将再次失败
-p
。@MacUsers:所以也为另一个选项添加一个
default=None
hasattr()
是我的方法
default=None
实际上是将它们都添加到名称空间中,这可能会在我的原始脚本中带来一些其他问题。谢谢你。干杯您的每个参数
default
正在覆盖解析器的
SUPPRESS
default。@hpaulj:确实;在我的回答中更明确了一点。
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'
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')