Python argparse:命令行参数,可以命名或定位 [英] Python argparse: command-line argument that can be either named or positional
问题描述
我正在尝试制作一个使用argparse
模块来解析命令行选项的Python程序.
I am trying to make a Python program that uses the argparse
module to parse command-line options.
我想做一个可选的参数,可以命名也可以是位置参数.例如,我希望myScript --username=batman
做与myScript batman
相同的事情.我还希望没有用户名的myScript
有效.这可能吗?如果是这样,怎么办?
I want to make an optional argument that can either be named or positional. For example, I want myScript --username=batman
to do the same thing as myScript batman
. I also want myScript
without a username to be valid. Is this possible? If so, how can it be done?
我尝试了类似于以下代码的各种操作,但均未成功.
I tried various things similar to the code below without any success.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--user-name", default="admin")
group.add_argument("user-name", default="admin")
args = parser.parse_args()
编辑:上面的代码引发了异常,提示ValueError: mutually exclusive arguments must be optional
.
The above code throws an exception saying ValueError: mutually exclusive arguments must be optional
.
我正在OS X 10.8.4上使用Python 2.7.2.
I am using Python 2.7.2 on OS X 10.8.4.
编辑:我尝试了Gabriel Jacobsohn的建议,但在所有情况下都无法正常工作.
EDIT: I tried Gabriel Jacobsohn's suggestion but I couldn't get it working correctly in all cases.
我尝试过:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--user-name", default="admin", nargs="?")
group.add_argument("user_name", default="admin", nargs="?")
args = parser.parse_args()
print(args)
并运行myScript batman
将打印Namespace(user_name='batman')
,但是myScript -u batman
和myScript --user-name=batman
将打印Namespace(user_name='admin')
.
and running myScript batman
would print Namespace(user_name='batman')
, but myScript -u batman
and myScript --user-name=batman
would print Namespace(user_name='admin')
.
我试图在第一行add_argument
行中将名称user-name
更改为user_name
,有时这会导致名称空间中的batman
和admin
或错误,这取决于我如何运行程序.
I tried changing the name user-name
to user_name
in the 1st add_argument
line and that sometimes resulted in both batman
and admin
in the namespace or an error, depending on how I ran the program.
我尝试在第二个add_argument
行中将名称user_name
更改为user-name
,但这将显示Namespace(user-name='batman', user_name='admin')
或Namespace(user-name='admin', user_name='batman')
,具体取决于我如何运行该程序.
I tried changing the name user_name
to user-name
in the 2nd add_argument
line but that would print either Namespace(user-name='batman', user_name='admin')
or Namespace(user-name='admin', user_name='batman')
, depending on how I ran the program.
推荐答案
ArgumentParser 的工作方式是,在解析可选参数之后,它始终会检查任何尾随的位置参数.因此,如果您有一个与可选参数同名的位置参数,并且它没有出现在命令行的任何位置,则可以确保覆盖该可选参数(使用其默认值或 None ).
The way the ArgumentParser works, it always checks for any trailing positional arguments after it has parsed the optional arguments. So if you have a positional argument with the same name as an optional argument, and it doesn't appear anywhere on the command line, it's guaranteed to override the optional argument (either with its default value or None).
坦率地说,这对我来说似乎是个错误,至少在相互排斥的组中使用时,因为如果您明确指定了参数,那将是一个错误.
Frankly this seems like a bug to me, at least when used in a mutually exclusive group, since if you had specified the parameter explicitly it would have been an error.
也就是说,我建议的解决方案是为位置参数指定一个不同的名称.
That said, my suggested solution, is to give the postional argument a different name.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-u','--username')
group.add_argument('static_username',nargs='?',default='admin')
然后在解析时,使用可选的 username (如果存在),否则回退到位置 static_username .
Then when parsing, you use the optional username if present, otherwise fallback to the positional static_username.
results = parser.parse_args()
username = results.username or results.static_username
我意识到这不是一个特别整洁的解决方案,但我认为任何答案都不会.
I realise this isn't a particularly neat solution, but I don't think any of the answers will be.
这篇关于Python argparse:命令行参数,可以命名或定位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!