3

我正在编写一个带有 argparse 的工具,它将从命令行获取源目录列表并处理其中的所有文件。最终,当调用 parse_args 时,会扫描每个目录以查找要处理的文件,并将文件列表放入files返回的命名空间之外的属性中。

parser = argparse.ArgumentParser()
parser.add_argument('-s', '--sources'
    , dest = 'files'
    , default = 'results/e1653a3'
    , nargs = '*'
    , metavar = 'SOURCE'
    , action = ConcatAction
    , type = FileList
)
args = parser.parse_args()

在这里,该FileList函数采用目录名称并返回文件列表。ConcatAction是一个扁平化列表列表的动作。结果是我可以将我的工具称为tool.py -s dir1 dir2,并args.files包含两个目录中的所有文件。

默认情况下,我希望它扫描多个目录;但是,将列表传递给默认值:

, default = ['dir1', 'dir2']

回避了 argparse 的类型转换系统,因此FileList()永远不会被调用,并且args.files包含 list ['dir1', 'dir2'],而不是扫描的文件。如果我尝试

, default = 'dir1 dir2'

然后进行一次调用FileList('dir1 dir2')而不是两次调用FileList('dir1') FileList('dir2')

我知道我可以只处理 argparse 之外的源目录以获得我想要的功能,但是无论如何让 argparse 对默认值列表执行类型转换?

4

1 回答 1

2

正如您所注意到的,字符串默认值通过 type 函数传递,而所有其他默认值都简单地分配给属性(未更改)。我认为解决方案是在默认情况下构建您希望在命名空间中看到的确切文件列表。

parser.add_argument('-s', '--sources'
    , dest = 'files'
    , default = [FileList('dir1'), FileList('dir2')] # exact file list
    , nargs = '*'
    , metavar = 'SOURCE'
    , action = ConcatAction
    , type = FileList
)

我会让你担心应用扁平化动作。

或者您可以使用所需的文件列表初始化命名空间。在这种情况下, 将default被忽略。

ns = argparse.NameSpace(files = [FileList('dir1'), FileList('dir2')])
# or
ns = argparse.NameSpace(files = ['dir1/file1','dir1/file2','dir2/file1',...])
parser.parse_args(sys.argv, namespace=ns)
于 2013-11-04T06:42:56.513 回答