我想得到一个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。
答案 0 :(得分:1)
可能会发生几件事情。一种可能性是../User/Desktop/Data/*.png
与任何文件都不匹配,因此不会扩展。这只会在类似UNIX的外壳上发生(或者我想是PowerShell)。另一种可能性是您在Windows上使用cmd.exe
,而根本不进行通配符扩展。鉴于您在Windows上使用Anaconda提示符,我倾向于后一种可能性作为解释。
由于您要查找文件夹中所有PNG的列表,因此完全不需要依赖Shell。在argparse
中集成和不集成都可以通过多种方式在Python中完成相同操作。
让我们从实现列表功能开始。给定目录,以下是一些获取其中所有PNG列表的方法:
使用glob.glob
(推荐选项)。这可以递归到子目录,也可以不递归到子目录,具体取决于您想要的内容:
mydir = '../User/Desktop/Data/'
pngs = glob.glob(os.path.join(mydir, '*.png'))
要递归到子文件夹,只需添加recursive=True
仅关键字选项。
使用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[:]
,该行将禁止子目录搜索。
一个始终非递归的相关方法是使用os.listdir
,这与Python的ls
或dir
命令大致相同:
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
的任何级别。这里有几个例子:
只需从参数中获取所有目录,然后将其列出即可:
parser.add_argument("-p", "--pics", action='store', help="picture files", required=True)
处理完参数后:
print(list_pngs(args.pics))
使用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中的说明在应用程序中进行扩展。