Python argparse,位置参数后的值

时间:2019-01-26 23:10:06

标签: python python-3.x argparse

所以我正在编写这个非常小的程序来执行http获取和发布请求。请求如下:

requestApp.py help
requestApp.py help get
requestApp.py help post
requestApp.py get [-v] [-h key:value] URL
requestApp.py post [-v] [-h key:value] [-d inline-data] [-f file] URL

如您所见,-v,-h,-d,-f,URL参数是可选的。 get和post参数是非可选的。我将向您展示与这种情况相关的程序片段:

parser = argparse.ArgumentParser(description='httpc is a curl-like application but supports HTTP protocol only.')
parser.add_argument('command', type=str, help=help_output())
parser.add_argument('url', action='store_true', help='The URL that will be provided to perform the requested command.')
parser.add_argument('-v', '--verbose', action='store_true')

command参数将是help,get或post,而url参数是不言自明的。我的问题与上面的第二和第三条命令有关,即:

requestApp.py help get
requestApp.py help post

如何确保在键入help get时,get不会在URL中注册(与help post相同)。另外,当我包含URL时,我希望将其存储在URL参数内。我是否必须手动评估通过if语句传递的参数?还是有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

使用argparse进行操作非常复杂,这里是如何使用docopt进行操作,docopt解析使用模式并返回字典:

"""
Usage:
    requestApp help [get|post]
    requestApp get [-v] [-k=key:value] <URL>
    requestApp post [-v] [-k=key:value] [-d=data] [-f file] <URL>

Options:
    -v --verbose       This is verbose mode
    -d=data            This option does this
    -k=key:value       This one does that
    -f file            This one is magic
"""

from docopt import docopt

ARGS = docopt(__doc__)

例如,使用requestApp.py post -k hello:world -f myfile.txt google.com docopt将返回:

{
  "--verbose": false, 
  "-d": None, 
  "-f": "myfile.txt", 
  "-k": "hello:world", 
  "<URL>": "google.com", 
  "get": false, 
  "help": false, 
  "post": true
}

那么您可以做:

if ARGS['help']:
    if ARGS['get']: pass                # requestApp help get
    else if ARGS['post']: pass          # requestApp help post
    else: pass                          # requestApp help
    exit()

if ARGS['get']: pass                    # requestApp get
else if ARGS['post']: pass              # requestApp post

if ARGS['--verbose']: print("this is just the beginning") 

-h是默认情况下(用于帮助)的保留选项,使docopt返回使用模式并退出。 如果您尝试使用docopt

之类的非法命令,requestApp help unicorn会将使用模式返回到stdout并退出。

答案 1 :(得分:1)

至少在不使用子解析器路线的情况下,可能最接近argparse解决方案的地方是:

import argparse
import sys
print(sys.argv)
parser = argparse.ArgumentParser()
parser.add_argument('-k', '--keyvalue')
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-d', '--data')
parser.add_argument('-f', '--file')
parser.add_argument('pos1', choices = ['help', 'get', 'post'])
parser.add_argument('pos2')

args = parser.parse_args()
print(args)

得到的帮助是:

1744:~/mypy$ python stack54383659.py get aurl -h
['stack54383659.py', 'get', 'aurl', '-h']
usage: stack54383659.py [-h] [-k KEYVALUE] [-v] [-d DATA] [-f FILE]
                        {help,get,post} pos2

positional arguments:
  {help,get,post}
  pos2

optional arguments:
  -h, --help            show this help message and exit
  -k KEYVALUE, --keyvalue KEYVALUE
  -v, --verbose
  -d DATA, --data DATA
  -f FILE, --file FILE

合身并不完美。例如,您可以仅提供help,但是您可以仅提供-h。第二个位置值可以是任何字符串,“ get”,有效的URL或其他任何内容。您自己的代码必须对此进行验证。 key:value位需要您自己进行解析。

argparse解析optionals的方式可以以任何顺序发生。这两个位置必须以给定的顺序(相对于彼此)出现。


在较新的Python中,我可以将最后一个位置更改为“可选”,并使用新的intermixed解析器。那将允许我只给出“帮助”(或只是“得到”):

parser.add_argument('pos2', nargs='?')
args = parser.parse_intermixed_args()
如果两个位置值由标志分开,则需要

intermixed。由于某些复杂的原因,常规解析可能会消耗“?”参数过早地给您留下了额外的无法识别的字符串。

另一种方法是定义所有标记的参数,并使用parse_known_args。非标志值将在extras列表中,您可以根据需要对其进行解析。像optparse这样的较早的解析器实际上就是这样做的。 argparse也增加了处理位置参数的能力,但严格按位置而不是按值。