【问题标题】:optional python arguments without dashes but with additional parameters?没有破折号但带有附加参数的可选python参数?
【发布时间】:2018-07-25 13:00:15
【问题描述】:

我想在 Python 中做的是接受以下格式的参数:

script.py START | STOP | STATUS | MOVEABS <x> <y> | MOVEREL <x> <y>

也就是说,

  1. 我不想处理连字符;
  2. 我有多种可能性,其中一种是必需的;
  3. 每个都是互斥的;
  4. 某些命令(例如 moveabs 和 moverel)具有额外的必需参数,但这些参数不应与任何其他参数一起出现。

这可以在 python 中完成吗?我会使用 argparse 还是其他东西?谢谢。

【问题讨论】:

标签: python argparse


【解决方案1】:

add_parser 使用子解析器可以解决问题

import argparse
parser = argparse.ArgumentParser(prog='script.py')
sp = parser.add_subparsers(dest='cmd')
for cmd in ['START', 'STOP', 'STATUS']:
    sp.add_parser(cmd)
for cmd in ['MOVEABS', 'MOVEREL']:
    spp = sp.add_parser(cmd)
    spp.add_argument('x', type=float)
    spp.add_argument('y', type=float)
parser.print_help()
args = parser.parse_args()
print(args)

制作类似的东西:

2137:~/mypy$ python2.7 stack23304740.py MOVEREL -h
usage: script.py [-h] {START,STOP,STATUS,MOVEABS,MOVEREL} ...

positional arguments:
  {START,STOP,STATUS,MOVEABS,MOVEREL}

optional arguments:
  -h, --help            show this help message and exit

usage: script.py MOVEREL [-h] x y

positional arguments:
  x
  y

optional arguments:
  -h, --help  show this help message and exit

2146:~/mypy$ python2.7 stack23304740.py MOVEREL 1.0 2.0
...
Namespace(cmd='MOVEREL', x=1.0, y=2.0)

2147:~/mypy$ python2.7 stack23304740.py START
...
Namespace(cmd='START')

MOVEREL 参数可以命名为&lt;x&gt;&lt;y&gt;,但是您必须通过args['&lt;y&gt;'] 而不是args.y 访问它们。 metavar='&lt;x&gt;' 可用于更改显示,但不能更改命名空间名称。

您也可以使用spp.add_argument('point', nargs=2, type=float)。不幸的是,在nargs=2 案例http://bugs.python.org/issue14074 中,有一个错误使我们无法使用元变量。

【讨论】:

    【解决方案2】:

    使用docopt 你可以很容易地做到这一点。

    先安装docopt

    $ pip install docopt
    

    script.py:

    """
    Usage:
        script.py (start | stop | status | moveabs <x> <y> | moverel <x> <y>)
    """
    from docopt import docopt
    
    if __name__ == "__main__":
        args = docopt(__doc__)
        print args
    

    并运行它:

    首先显示基本帮助:

    $ python script.py
    Usage:
        script.py (start | stop | status | moveabs <x> <y> | moverel <x> <y>)
    

    然后尝试子命令:

    开始

    $ python script.py start
    {'<x>': None,
     '<y>': None,
     'moveabs': False,
     'moverel': False,
     'start': True,
     'status': False,
     'stop': False}
    

    停止

    $ python script.py stop
    {'<x>': None,
     '<y>': None,
     'moveabs': False,
     'moverel': False,
     'start': False,
     'status': False,
     'stop': True}
    

    移动

    $ python script.py moveabs 11 22
    {'<x>': '11',
     '<y>': '22',
     'moveabs': True,
     'moverel': False,
     'start': False,
     'status': False,
     'stop': False}
    

    移动

    $ python script.py moverel 11 22
    {'<x>': '11',
     '<y>': '22',
     'moveabs': False,
     'moverel': True,
     'start': False,
     'status': False,
     'stop': False}
    

    【讨论】:

    • argparse 解决方案不会产生不必要的数据字段,因此我觉得它更简洁、更健壮。
    猜你喜欢
    • 2012-07-03
    • 2021-05-06
    • 1970-01-01
    • 2021-10-20
    • 2018-04-22
    • 1970-01-01
    • 2020-11-25
    • 2012-07-15
    • 2020-07-07
    相关资源
    最近更新 更多