【问题标题】:Parsing command line input for numbers解析数字的命令行输入
【发布时间】:2011-01-18 16:01:52
【问题描述】:

我正在编写一个命令行应用程序,并希望用户能够输入数字作为单个数字或一个范围。所以,例如:

$ myapp -n 3,4,5,6

$ myapp -n 3-6

我希望我的应用将这些放入 Python 列表中,例如 [3, 4, 5, 6] 我正在使用optparse,但不确定如何从这两种输入样式创建列表。一些示例代码会很棒。

编辑

我也希望能够输入多个范围:

$ myapp -n 22-27, 51-64

【问题讨论】:

标签: python parsing command-line


【解决方案1】:
import argparse

def parse_range(astr):
    result = set()
    for part in astr.split(','):
        x = part.split('-')
        result.update(range(int(x[0]), int(x[-1]) + 1))
    return sorted(result)

parser = argparse.ArgumentParser()
parser.add_argument('-n', type=parse_range)
args = parser.parse_args()
print(args.n)

产量

% script.py -n 3-6
[3, 4, 5, 6]

% script.py -n 3,6
[3, 6]

% script.py -n 22-27,51-64 
[22, 23, 24, 25, 26, 27, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]

【讨论】:

  • 我还希望能够输入多个范围,例如 myapp 22-27、51-64
  • @normski:对。上面的代码可以处理,只要22-27,51-64之间不加空格即可。 (这样整个字符串被加载到opt.n。)
【解决方案2】:

如果你在字符串中有 n-arg,你可以这样做:

def f(s):
    if '-' in s:
        i = s.index('-')
        return range(*map(int, s.split('-')))
    return map(int, s.split(','))

一些例子:

In [3]: s = '1, 2, 3, 4, 5, 6'

In [4]: f(s)
Out[4]: [1, 2, 3, 4, 5, 6]

In [5]: f('3-6')
Out[5]: [3, 4, 5]

In [6]: f('3-16-3')
Out[6]: [3, 6, 9, 12, 15]

【讨论】:

  • 我喜欢这个解决方案。我想看看一些输入验证,真的:)如果输入列表很大,那将是非常不理想的,但我怀疑不是。
  • 这也不包括上边界。
【解决方案3】:

您可以定义您的参数并在保存之前使用optparse callback 处理您的输入:

from optparse import OptionParser

parser = OptionParser()

def create_range_callback(option, opt, value, parser):
    i, j = map(int, value.split('-'))
    setattr(parser.values, option.dest, range(i, j+1))

parser.add_option("-r", "--range", action="callback", 
                  callback=create_range_callback, 
                  type="string", dest='list')

(options, args) = parser.parse_args()

print options.list

现在做:

python2.7 test.py -r 1-5

输出:

[1, 2, 3, 4, 5]

【讨论】:

    【解决方案4】:

    使用Python's range function。解析用户的输入,用“-”字符分割,然后将这些参数传递给 range。

    您的代码可能如下所示:

    parameters = input.split('-')
    completeRange = range(int(parameters[0]), int(parameters[1]))
    

    如果他们输入单独的数字,您可以很容易地将其解析成一个列表。

    【讨论】:

    • 根据需要,这将不包括上边界。
    【解决方案5】:

    您可以使用optparse 库。

    例子:

    from optparse import OptionParser
    
    opt_parser = OptionParser(version="%prog 0.1")
    opt_parser.usage = '%prog [options]\n\nTCP protocol reengineering tool'
    
    # Options
    opt_parser.add_option('-n', default="1,2,3")
    (options, args) = opt_parser.parse_args()
    
    list = []
    for s in options.n.split(","):
        list.append(int(s))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2015-04-22
      • 1970-01-01
      相关资源
      最近更新 更多