【问题标题】:Python: argument parser - multiple arguments without "--" allowed, not requiredPython:参数解析器 - 允许不带“--”的多个参数,不是必需的
【发布时间】:2018-04-08 10:10:39
【问题描述】:

我正在努力编写一个简单的 python 脚本(一个伪 git),这将允许我使用如下命令从命令行/shell 调用它:

$ python script.py init

我在网上找到了一些解决方案,这使我能够这样做,但是问题不大。我希望“添加”函数也接受其他参数(一般是字符串,表示文件名)。

我找到了一种解决方法,但它看起来不太好。有没有办法重构代码,以便“添加”也接受其他参数并让我稍后访问它们?重要的事情:我不希望它们添加“--”,我宁愿通过简单地在两个参数之间添加空格来分隔它们。

我在 add_argument 中找到“nargs='+' 选项,但我不知道如何重定向参数以调用正确的函数。

这是我目前写的代码:

import argparse
import sys

def init():
    print("init method call")

def add():
    if(len(sys.argv)>2):
        print("valid add method call")
    else:
        print("invalid call")

def commit():
    print("commit method call") 

def status():
    print("status method call") 

def test():
    print("test method call")   

FUNCTION_MAP = {'init' : init,
                'status' : status,
                'commit': commit}

if __name__ == '__main__':
    if(len(sys.argv)>1 and sys.argv[1] == "add"):
        add()
    else:           
        parser = argparse.ArgumentParser()
        parser.add_argument('command', choices=FUNCTION_MAP.keys())
        args = parser.parse_args()
        func = FUNCTION_MAP[args.command]
        func()

【问题讨论】:

  • 使用上面链接的文档,您可以查看将init()add()commit() 作为子解析器,这样您就可以为每个函数设置特定的标志。
  • 但是我可以在没有 '-' 或 '--' 的情况下给他们打电话吗?我已经找到了那些文档,但是在浏览它们之后,我有了不同的感觉,并决定改为询问 SO 社区。编辑:我还想添加什么来接受更多参数
  • Click 可能对您的情况有用,尤其是@click.argument
  • @Adonis 谢谢,但我宁愿在这个例子中使用 argparse

标签: python argparse


【解决方案1】:

这里有 2 个选项 - 采用额外的位置,并使用或忽略这些值。或者使用子解析器。

import argparse

def add(args):
    print("add:", args)

def status(args):
    values = getattr(args,'values',None)
    if values and len(values)>0:
        # error message and method of your choice
        print('oops - got values', args)
    print("status method call")

FUNCTION_MAP = {'add' : add,
                'status' : status}

if __name__ == '__main__':

        parser = argparse.ArgumentParser()
        parser.add_argument('command', choices=FUNCTION_MAP.keys())
        parser.add_argument('values', nargs='*')
        args = parser.parse_args()
        func = FUNCTION_MAP[args.command]
        func(args)

        print('\nWIth subparsers')
        parser = argparse.ArgumentParser()
        sp = parser.add_subparsers(dest='command')
        spp = sp.add_parser('add')
        spp.add_argument('values', nargs='*')
        spp = sp.add_parser('status')
        args = parser.parse_args()
        func = FUNCTION_MAP[args.command]
        func(args)

样本运行

1906:~/mypy$ python3 stack49691897.py add 1 2 3
add: Namespace(command='add', values=['1', '2', '3'])

WIth subparsers
add: Namespace(command='add', values=['1', '2', '3'])
1907:~/mypy$ python3 stack49691897.py status
status method call

WIth subparsers
status method call
1907:~/mypy$ python3 stack49691897.py status 1 2 3
oops - got values Namespace(command='status', values=['1', '2', '3'])
status method call

WIth subparsers
usage: stack49691897.py [-h] {add,status} ...
stack49691897.py: error: unrecognized arguments: 1 2 3

argparse 文档还演示了一种使用子解析器和默认值的方法,可以有效地实现您的FUNCTION_MAP

【讨论】:

  • 谢谢@hpaulj :) 我会调查的!但是是否可以不为 add 指定可接受的值,而是说我们可以接受所有内容并在代码中稍后处理验证它?
  • parse_known_args一起玩。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多