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

parse_args all .png files from a parser argument

我想在 运行 之后得到一个 arg.pics 其中 returns 类似 ['pic1.png', 'pic2.png', 'pic3.png'] 的东西(任意解析所有 .png 格式的文件)(test.py):

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 returns ['../User/Desktop/Data/*.png'] 相反..

我使用的方法正确吗?我听说使用 *.png 会在输入后扩展为 .png 文件,但我这边似乎不是这样。

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

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

Anaconda 命令提示符默认使用cmd.exe,不支持通配符扩展。你可以使用 PowerShell instead, which does understand wildcards. Alternatively, you can do the expansion in your application as described in Mad Physicist's .

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

由于您要查找文件夹中所有 PNG 的列表,因此根本不需要依赖 shell。在 Python 中有很多方法可以做同样的事情,无论是否集成在 argparse.

让我们从实现列表功能开始。给定一个目录,这里有一些方法可以获取其中所有 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.

  4. 结尾的文件夹名称

假设您选择了其中一种方法并创建了一个接受文件夹和 returns 文件列表的函数:

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)