繁体   English   中英

如何将Argparse参数的默认值设置为位置参数的值?

[英]How do I set an Argparse argument's default value to a positional argument's value?

我有一个发送GET请求的python脚本。 它使用Argparse来获取三个参数:

  1. 地址 :发送GET请求的位置
  2. 主机 :在GET请求中声明的主机
  3. 资源 :正在请求哪个资源

示例用法可能是:

$ python get.py 198.252.206.16 stackoverflow.com /questions/ask

但是,在大多数情况下,只需要提供主机和资源,因为主机将解析为该地址:

 $ host -t a stackoverflow.com
 stackoverflow.com has address 198.252.206.16

所以期望的用法可能是:

$ python get.py stackoverflow.com /questions/ask

如何设置Argparse以使Address参数的默认值为Host参数的值?


我被要求显示当前解析参数的代码。 这里是:

import argparse

parser = argparse.ArgumentParser(description=
         'Send a GET request and obtain the HTTP response header and/or body.')

parser.add_argument("-v", "--verbose",
                    help="Turn on verbose mode.",
                    action="store_true")
parser.add_argument("-p", "--port",
                    type=int,
                    default=80,
                    help="Which port to use when sending the GET request."
parser.add_argument("address",
                    help="Where to send the GET request to.")
parser.add_argument("host",
                    help="Which Host to declare in the GET request.")   
parser.add_argument("resource",
                    help="Which resource to request.")

parser.parse_args()

nargs='?' 很好地处理这种情况。 如果只有2个字符串,则将它们分配给hostresource ,并且address获取其默认值( None )。 如果3个字符串,则将它们分配给所有3.如果有帮助,请考虑行为? re模式。

解析器完成后,很容易将host值分配给address 尝试在parse_args执行该任务没有意义(因为主机值还不知道)。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("address", nargs='?')
parser.add_argument("host")
parser.add_argument("resource")
args = parser.parse_args()

if args.address is None:
    args.address = args.host
print(args)

用法是:

usage: get.py [-h] [address] host resource

[]整齐地标记可选的位置参数。

如果您尝试使用ONLY位置参数来实现所描述的行为,则可以使用list参数(nargs),如下所示:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("args", nargs="+")
parsed = parser.parse_args()
args = parsed.args
if len(args) == 3:
    ip, host, address = args
    print ip, host, address
elif len(args) == 2:
    ip, host, address = args[0], args[0], args[1]
    print ip, host, address
else:
    print "Invalid args"

但是这个hacky不仅会失去argparse提供的好处(你必须手动验证参数)。 我建议你使用可选参数。 也许是这样的:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-host", required=True)
parser.add_argument("-res", required=True)
parser.add_argument("-ip", required=False)
args = parser.parse_args()

ip = args.ip if args.ip else args.host
print args.host, args.res, ip

并执行它:

python2.7 test.py -host hello -res world

这里有两个合理的选择,你选择哪个取决于你使用位置参数而不是--options的依赖程度。

  1. 使用nargs='+'添加位置参数。 解析args后,检查该列表的长度。 如果是3,则将它们设置为地址,主机和资源。 如果为2,则将它们设置为主机和资源,并从主机复制地址。 否则,打印用法消息并引发异常。

  2. 将主机和资源保留为位置参数。 将地址更改为选项。 这意味着CLI将改为:

python get.py stackoverflow.com /questions/ask --address 198.252.206.16

您可以将默认值设置为None ,然后在解析args之后检查它是否为none,我认为在argparse中无论如何都将其设置为自动默认为另一个位置arg。

您选择的是个人偏好,我更喜欢2个(可选参数应该是,根据定义,选项),因为它更适合可用工具 - 如果你弯曲argparse行为像1那么你将不得不另外覆盖--help选项,使用消息等因为自动生成的默认值会产生误导。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM