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: 互斥参数必须是可选的
.
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')
.
我尝试在第 1 个 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 positional 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屋!