Python argparse:命令行参数,可以是命名的也可以是位置的

时间:2013-07-11 15:58:08

标签: python python-2.7 command-line-arguments argparse python-2.x

我正在尝试创建一个使用argparse模块来解析命令行选项的Python程序。

我想创建一个可以命名或位置的可选参数。例如,我希望myScript --username=batmanmyScript batman做同样的事情。我还希望myScript没有用户名有效。这可能吗?如果是这样,怎么办呢?

我尝试了类似下面代码的各种事情而没有任何成功。

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的异常。

我在OS X 10.8.4上使用Python 2.7.2。

编辑:我尝试了Gabriel Jacobsohn的建议,但在所有情况下我都无法正常工作。

我试过了:

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 batmanmyScript --user-name=batman会打印Namespace(user_name='admin')

我尝试在第一个user-name行中将名称user_name更改为add_argument,有时会在命名空间中导致batmanadmin错误,取决于我如何运行程序。

我尝试将名称user_name更改为第user-name行中的add_argument,但会打印Namespace(user-name='batman', user_name='admin')Namespace(user-name='admin', user_name='batman'),具体取决于我的运行方式该计划。

3 个答案:

答案 0 :(得分:7)

ArgumentParser 的工作方式,它总是在解析可选参数后检查任何尾随位置参数。因此,如果您的位置参数与可选参数具有相同的名称,并且它不会出现在命令行的任何位置,则可以保证覆盖可选参数(使用其默认值或 )。

坦率地说,这对我来说似乎是一个错误,至少在互斥组中使用时,因为如果您明确指定了参数,那将是一个错误。

那就是说,我建议的解决方案是给位置参数一个不同的名称。

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-u','--username')
group.add_argument('static_username',nargs='?',default='admin')

然后在解析时,使用可选的用户名(如果存在),否则回退到位置 static_username

results = parser.parse_args()
username = results.username or results.static_username

我意识到这不是一个特别简洁的解决方案,但我认为不会有任何答案。

答案 1 :(得分:4)

这是一个我认为可以做你想要的一切的解决方案:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--user-name", default="admin")
    # Gather all extra args into a list named "args.extra"
    parser.add_argument("extra", nargs='*')
    args = parser.parse_args()
    # Set args.user_name to first extra arg if it is not given and len(args.extra) > 0
    if args.user_name == parser.get_default("user_name") and args.extra:
        args.user_name = args.extra.pop(0)
    print args

如果您运行myScript -u batmanmyScript --user-name=batman,则args.user_name设置为“蝙蝠侠”。如果您执行myScript batman,则args.user_name再次设置为“蝙蝠侠”。最后,如果你只是myScriptargs.user_name设置为'admin'。

此外,作为额外的奖励,您现在拥有传递给args.extra中存储的脚本的所有额外参数。希望这会有所帮助。

答案 2 :(得分:0)

尝试使用" nargs" add_argument方法的参数。 这样它对我有用。 现在您可以添加两次用户名, 所以如果你愿意,你必须检查它并引发错误。

import argparse
if __name__ == '__main__':
   parser = argparse.ArgumentParser()
   parser.add_argument("-u", "--user-name", default="admin")
   parser.add_argument("user_name", default="admin", nargs="?")
   args = parser.parse_args()
   print(args)