代码之家  ›  专栏  ›  技术社区  ›  ejm Xan

在python中处理前缀表示法中的命令行参数

  •  6
  • ejm Xan  · 技术社区  · 15 年前

    我试图用python解析一个命令行,如下所示:

    $ ./command -o option1 arg1 -o option2 arg2 arg3
    

    换句话说,该命令接受无限数量的参数,并且每个参数前面可以有选择地加上 -o 选项,与该参数具体相关。我认为这叫做“前缀符号”。

    在Bourne Shell中,我将执行以下操作:

    while test -n "$1"
    do
        if test "$1" = '-o'
        then
            option="$2"
            shift 2
        fi
        # Work with $1 (the argument) and $option (the option)
        # ...
        shift
    done
    

    看看bash教程等。这似乎是公认的习惯用法,所以我猜bash是以这种方式优化以使用命令行参数的。

    尝试在Python中实现这个模式,我的第一个猜测是使用 pop() ,因为这基本上是一个堆栈操作。但我猜这在python上不会很好地工作,因为 sys.argv 顺序错误,必须像处理队列一样进行处理(即从左侧弹出)。我已经了解到,列表并没有针对在Python中用作队列进行优化。

    所以,我的想法是:转换 argv 到A collections.deque 使用 popleft() 反向 阿尔加夫 使用 reverse() 使用 () 或者只是使用int列表索引本身。

    有没有人知道更好的方法来实现这一点,否则我的哪些想法将是在Python中最好的实践?

    6 回复  |  直到 15 年前
        1
  •  6
  •   jfs    15 年前

    另一个stdlib模块: argparse

    p = argparse.ArgumentParser()
    p.add_argument('-o', action='append')
    for i in range(1, 4): p.add_argument('arg%d' % i)
    args = p.parse_args('-o option1 arg1 -o option2 arg2 arg3'.split())
    print args
    # -> Namespace(arg1='arg1', arg2='arg2', arg3='arg3', o=['option1', 'option2'])
    
        2
  •  5
  •   David Z    15 年前

    你可以做到

    argv.pop(0)
    

    它提取第一个元素并返回它。不过,这可能效率低下。也许吧。我不知道怎么做 argv 在发动机罩下执行。(如果效率是 那个 重要提示,为什么要使用python?)

    不过,一个更为蟒蛇式的解决方案是迭代列表而不弹出元素。像这样:

    o_flag = False
    for a in argv:
        if a == '-o':
            o_flag = True
            continue
        # do whatever
        o_flag = False
    

    另外,我认为 optparse 模块值得一提;它是在Python程序中处理选项和参数的相当标准的,尽管对于这个任务来说,它可能是多余的,因为您已经有了几个功能完美的解决方案。

        3
  •  4
  •   Ivan X    11 年前

    通过导入sys,然后将sys.argv[1:]分配给变量(例如“args”),可以拥有bourne/bash中相当于“shift”的python函数。然后可以使用args=args[1:]向左移动一次,或者使用更大的数字进行多次移动。参数索引将从0而不是1开始。上面的例子看起来像:

    import sys
    args = sys.argv[1:]
    while len(args):
        if args[0] == '-o':
            option = args[1]
            args = args[2:] # shift 2
        # Work with args[0] (the argument) and option (the option)
        # ...
        args = args[1:] # shift
    
        4
  •  2
  •   jkasnicki    15 年前

    类似:

    for arg in sys.argv[1:]:
      # do something with arg
    

    应该对你很好。除非您期望有非常多的参数,否则我会选择最简单的代码(不要太担心性能)。argv[1:]忽略第一个argv值,该值将是脚本的名称。

        5
  •  2
  •   Etaoin    15 年前

    无需重新发明轮子:The getopt 模块正是为此而设计的。如果这不适合你的需要,试试 optparse 模块,更灵活,更复杂。

        6
  •  0
  •   rashok    7 年前

    在蟒蛇中 del sys.argv[1] 执行的操作与 shift 在里面 bash . 在蟒蛇中 sys.argv 是一个列表。删除索引上的元素 1 一样 转移 在里面 猛击 .

    下面的示例python脚本将有助于跳过 -o 并考虑所有其他论点。

    #!/usr/bin/python
    import sys
    
    if __name__ == '__main__':
        while len(sys.argv) > 1:
            if sys.argv[1] != "-o":
                print sys.argv[1]
            del sys.argv[1]