argparse:如何解析单个字符串参数或一个列出许多参数的文件?

时间:2016-09-28 21:23:46

标签: python argparse

我有一个用例,我希望用户能够作为argparse的参数提供一个字符串或一个文件名,其中每一行都有一个字符串。

假设用户启动./myscript.py -i foobar

我正在寻找的逻辑流程是这样的:

脚本确定字符串foobar是否是可读文件。 如果它确实是一个可读文件,我们从脚本中调用一些函数,将foobar中的每一行作为参数传递给该函数。如果foobar不是可读文件,我们调用相同的函数,但只使用字符串foobar作为参数并返回。

我无法保证文件名参数将具有特定的扩展名(甚至根本不具有扩展名)。

有没有更多的pythonic方式来做到这一点除了完全按照我上面描述的那样编写逻辑?我浏览了argparse tutorial并没有看到任何内容,但是认为文件名会有一些特定的钩子作为参数似乎也是合理的,所以我想我会问。

2 个答案:

答案 0 :(得分:1)

一种方式是:

假设你已经创建了一个这样的解析器:

parser.add_argument('-i',  
                    help='...', 
                    type=function)

type指向function,它将是一个外部函数,用于评估用户的输入并确定它是string还是filename

您可以在documentation找到有关type的更多信息。

以下是演示type的使用的最小示例:

parser.add_argument('-d','--directory', 
                    type=Val_dir, 
                    help='...')
# ....

def Val_dir(dir):
    if not os.path.isdir(dir):
        raise argparse.ArgumentTypeError('The directory you specified does not seem to exist!')
    else:
        return dir

上面的例子表明,使用type,我们可以在解析时控制输入。当然,在您的情况下,该函数将实现另一个逻辑 - 评估输入是字符串还是文件名。

答案 1 :(得分:0)

这看起来不像argparse问题,因为你想要的只是一个字符串。该字符串可以是文件名或函数参数。对于parser,这些看起来会一样。另外argparse通常不用于运行函数。它用于解析命令行。您的代码确定如何处理该信息。

所以这是一个我认为可以完成任务的脚本(未经测试):

import argparse
def somefunction(*args):
    print(args)

if __name__=='__main__':
    parser=argparse.ArgumentParser()
    parser.add_argument('-i','--input')
    args = parser.parse_args()

    try:
        with open(args.input) as f:
            lines = f.read()
            somefunction(*lines)
            # or
            # for line in lines:
            #   somefuncion(line.strip())
    except:
        somefunction(arg.input)

argparse只提供args.input字符串。它是try / except块,决定了它的使用方式。

=====

这是一个前缀字符方法:

parser=argparse.ArgumentParser(fromfile_prefix_chars='@',
   description="use <prog -i @filename> to load values from file")
parser.add_argument('-i','--inputs')
args=parser.parse_args()
for arg in args.inputs:
     somefunction(arg)

这应该适用于如下文件:

 one
 two 
 three

https://docs.python.org/3/library/argparse.html#fromfile-prefix-chars