parse_args来自解析器参数的所有.png文件

时间:2018-09-20 13:48:59

标签: python windows python-3.x argparse glob

我想得到一个arg.pics,它在运行以下(['pic1.png', 'pic2.png', 'pic3.png'])之后返回类似test.py的内容(以任意解析.png格式的所有文件):

import argparse
import os

def parser_arg():
    par = argparse.ArgumentParser()
    parser = par.add_argument_group('pictures')
    parser.add_argument("-p", "--pics", nargs="+", help="picture files", required=True)
    arguments = par.parse_args()
    return arguments

args = parser_arg()

然后通过命令行运行脚本并输入

python test.py -p ../User/Desktop/Data/*.png

然后,args.pics返回['../User/Desktop/Data/*.png']

我使用正确的方法吗?听说使用*.png会在输入后扩展为.png文件,但我看来情况并非如此。

编辑:如果有帮助,我正在Windows 10上使用Anaconda Prompt。

2 个答案:

答案 0 :(得分:1)

可能会发生几件事情。一种可能性是../User/Desktop/Data/*.png与任何文件都不匹配,因此不会扩展。这只会在类似UNIX的外壳上发生(或者我想是PowerShell)。另一种可能性是您在Windows上使用cmd.exe,而根本不进行通配符扩展。鉴于您在Windows上使用Anaconda提示符,我倾向于后一种可能性作为解释。

由于您要查找文件夹中所有PNG的列表,因此完全不需要依赖Shell。在argparse中集成和不集成都可以通过多种方式在Python中完成相同操作。

让我们从实现列表功能开始。给定目录,以下是一些获取其中所有PNG列表的方法:

  1. 使用glob.glob推荐选项)。这可以递归到子目录,也可以不递归到子目录,具体取决于您想要的内容:

    mydir = '../User/Desktop/Data/'
    pngs = glob.glob(os.path.join(mydir, '*.png'))
    

    要递归到子文件夹,只需添加recursive=True仅关键字选项。

  2. 使用os.walk。这要灵活得多(因此需要更多工作),但也可以让您拥有递归或非递归解决方案:

    mydir = '../User/Desktop/Data/'
    pngs = []
    for path, dirs, files in os.walk(mydir):
        pngs.extend(f for f in files if f.lower().endswith('.png'))
        del dirs[:]
    

    要启用递归,只需删除行del dirs[:],该行将禁止子目录搜索。

  3. 一个始终非递归的相关方法是使用os.listdir,这与Python的lsdir命令大致相同:

    mydir = '../User/Desktop/Data/'
    pngs = [f for f in os.listdir(mydir) if f.lower().endswith('.png')]
    

    此版本不检查是否确实有文件。假定您没有以.png结尾的文件夹名称。

假设您选择了以下方法之一,并创建了一个接受文件夹并返回文件列表的函数:

def list_pngs(directory):
    return glob.glob(os.path.join(directory, '*.png'))

现在您知道如何列出文件夹中的文件了,您可以轻松地将其插入argparse的任何级别。这里有几个例子:

  1. 只需从参数中获取所有目录,然后将其列出即可:

    parser.add_argument("-p", "--pics", action='store', help="picture files", required=True)
    

    处理完参数后:

    print(list_pngs(args.pics))
    
  2. 使用type参数直接集成到argparse中:

    parser.add_argument("-p", "--pics", action='store', type=list_pngs, help="picture files", required=True)
    

    现在您可以直接使用参数,因为它将直接转换为列表:

    print(args.pics)
    

答案 1 :(得分:0)

您的方法是正确的。但是,如果您的外壳支持globbing并且模式实际上与任何文件匹配,那么脚本将仅将扩展的文件列表作为参数接收。否则,在大多数情况下,它将是模式本身。

Anaconda命令提示符默认情况下使用cmd.exe,但不支持通配符扩展。您可以改用PowerShell,它可以理解通配符。另外,您可以按照Mad Physicist的answer中的说明在应用程序中进行扩展。