python argparse - 要么两个可选参数,要么一个都没有
Posted
技术标签:
【中文标题】python argparse - 要么两个可选参数,要么一个都没有【英文标题】:python argparse - either both optional arguments or else neither one 【发布时间】:2012-12-30 07:05:57 【问题描述】:我有一个使用默认名称和密码的程序。我正在使用 argparse 来允许用户指定命令行选项,并且我想让用户能够为程序提供不同的名称和密码以供使用。所以我有以下内容:
parser.add_argument(
'-n',
'--name',
help='the login name that you wish the program to use'
)
parser.add_argument(
'-p',
'--password',
help='the password to log in with.'
)
但是只指定名称或只指定密码没有任何意义,但不指定任何一个都是有意义的。我注意到 argparse 确实有能力指定两个参数是互斥的。但我所拥有的是两个必须同时出现的论点。我如何得到这种行为? (我发现文档中提到了“参数组”,但它们似乎无法解决我的问题http://docs.python.org/2/library/argparse.html#argument-groups)
【问题讨论】:
我认为对参数进行后处理是不可能的? 没有什么是不可能的。我只想让 argparse 为我完成这项工作并告诉用户选项必须一起出现。 【参考方案1】:我相信处理这个问题的最好方法是对返回的命名空间进行后处理。 argparse
不支持这一点的原因是它一次解析参数 1。 argparse
很容易检查某些内容是否已被解析(这就是互斥参数起作用的原因),但要查看将来是否会解析某些内容并不容易。
一个简单的:
parser.add_argument('-n','--name',...,default=None)
parser.add_argument('-p','--password',...,default=None)
ns = parser.parse_args()
if len([x for x in (ns.name,ns.password) if x is not None]) == 1:
parser.error('--name and --password must be given together')
name = ns.name if ns.name is not None else "default_name"
password = ns.password if ns.password is not None else "default_password"
似乎就足够了。
【讨论】:
这是正确的,但 'name = ns.name 或 "default_name"' 更简单,我认为更容易阅读 'ns.name if ns.name is not None else ...' .但是,正如 mgilson 在其他地方指出的那样,如果用户为任一值传递了一个空字符串,则该空字符串将评估为 false,并且将使用默认值而不是提供的空字符串。sum(1 for x in (ns.name, ns.password) if x is not None)
也可以代替len([x for x in (ns.name,ns.password) if x is not None])
。
ns.name is None ^ ns.password is None
还不够吗? :D【参考方案2】:
这可能是我的做法。由于您拥有可以更改选项的现有默认值,因此请定义默认值,但不要将它们用作您的参数默认值:
default_name = "x"
default_pass = "y"
parser.add_argument(
'-n',
'--name',
default=None,
help='the login name that you wish the program to use'
)
parser.add_argument(
'-p',
'--password',
default=None,
help='the password to log in with.'
)
args = parser.parse_args()
if all(i is not None for i in [args.name, args.password]):
name = args.name
passwd = args.password
elif any(i is not None for i in [args.name, args.password]):
parser.error("Both Name and Password are Required!")
else:
name = default_name
passwd = default_pass
【讨论】:
小心这个。如果用户将密码设置为空字符串怎么办? 附带说明,您可以随时编辑已删除的答案并取消删除它:) 谢谢,挂在那里有点烦人。 好吧,更重要的是,如果你得到 10 票和复选标记,你可能会得到一个开明的徽章 :) 谢谢,并更新了对 None 的检查,而不是 Falseness。【参考方案3】:我知道这已经晚了两年多,但我找到了一种简洁明了的方法:
if bool(ns.username) ^ bool(ns.password):
parser.error('--username and --password must be given together')
^
是 Python 中的 XOR 运算符。要求在命令行中给出两个参数本质上是 XOR 测试。
【讨论】:
这不应该是 XNOR 吗? @KaustubhKarkareXOR
评估为 True
如果仅给出用户名或密码。上面描述了这种情况下的失败案例,所以应该是XOR
。以上是关于python argparse - 要么两个可选参数,要么一个都没有的主要内容,如果未能解决你的问题,请参考以下文章
Python 2.7 argparse:如何正确嵌套可选的互斥参数?