【问题标题】:Python argparse: nargs + or * depending on prior argumentPython argparse:nargs + 或 * 取决于先前的参数
【发布时间】:2011-05-06 03:01:27
【问题描述】:

我正在编写一个服务器查询工具,并且我有一些代码可以解析最顶部的参数:

# Parse arguments
p = argparse.ArgumentParser()
g = p.add_mutually_exclusive_group(required=True)
g.add_argument('--odam', dest='query_type', action='store_const',
        const='odam', help="Odamex Master query.")
g.add_argument('--odas', dest='query_type', action='store_const',
        const='odas', help="Odamex Server query.")
p.add_argument('address', nargs='*')
args = p.parse_args()

# Default master server arguments.
if args.query_type == 'odam' and not args.address:
    args.address = [
            'master1.odamex.net:15000',
            'master2.odamex.net:15000',
            ]

# If we don't have any addresses by now, we can't go on.
if not args.address:
    print "If you are making a server query, you must pass an address."
    sys.exit(1)

有没有更好的方法来做到这一点,最好是在解析器中?最后一个错误看起来有点不合时宜,如果我可以根据 --odam 或 ---odas 是否通过来为地址设置 nargs 那就太好了。我可以创建一个子解析器,但这会让帮助看起来有点奇怪,因为它会忽略命令的地址部分。

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    您可以使用自定义 argparse.Action 来做到这一点:

    import argparse
    import sys
    
    class AddressAction(argparse.Action):
        def __call__(self, parser, args, values, option = None):
            args.address=values
            if args.query_type=='odam' and not args.address:
                args.address=[
                    'master1.odamex.net:15000',
                    'master2.odamex.net:15000',
                    ]        
            if not args.address:
                parser.error("If you are making a server query, you must pass an address.")
    
    p = argparse.ArgumentParser()
    g = p.add_mutually_exclusive_group(required=True)
    g.add_argument('--odam', dest='query_type', action='store_const',
            const='odam', help="Odamex Master query.")
    g.add_argument('--odas', dest='query_type', action='store_const',
            const='odas', help="Odamex Server query.")
    p.add_argument('address', nargs='*', action=AddressAction)
    args = p.parse_args()
    

    产量

    % test.py --odas
    If you are making a server query, you must pass an address.
    % test.py --odam
    Namespace(address=['master1.odamex.net:15000', 'master2.odamex.net:15000'], query_type='odam')
    % test.py --odam 1 2 3
    Namespace(address=['1', '2', '3'], query_type='odam')
    

    【讨论】:

    • 正是我要找的东西!
    • 使用parser error而不是sys.exit()可能更有意义
    • 使用自定义操作的一个缺点是在解析参数时调用该操作,并且相关参数之后的参数尚未添加到值数组中。这使得可选参数对顺序敏感。为避免这种情况,不要添加自定义操作,只需在主调用 parse_args 后检查依赖关系,如果依赖失败则调用 p.error('explanation message')。这会打印出帮助文本并退出。
    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 2018-06-30
    • 2020-09-30
    • 2022-01-21
    • 1970-01-01
    • 2019-04-11
    • 2022-01-14
    • 2021-12-11
    相关资源
    最近更新 更多