如何在Python中列出目录中的所有文件并将其添加到列表中?
当前回答
从3.4版开始,有内置的迭代器,比os.listdir()高效得多:
pathlib:3.4版新增。
>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]
根据PEP428,pathlib库的目的是提供一个简单的类层次结构来处理文件系统路径和用户对它们进行的常见操作。
os.scandir():3.5版新增。
>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]
注意,os.walk()使用os.scandir()而不是3.5版的os.listdir(),根据PEP471,它的速度提高了2-20倍。
让我也推荐阅读ShadowRanger在下面的评论。
其他回答
这是我的通用函数。它返回文件路径列表而不是文件名,因为我发现这更有用。它有几个可选的参数,使其具有通用性。例如,我经常将其与pattern=“*.txt”或subfolders=True等参数一起使用。
import os
import fnmatch
def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
"""Return a list of the file paths matching the pattern in the specified
folder, optionally including files inside subfolders.
"""
match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
return [os.path.join(root, f)
for root, dirnames, filenames in walked
for f in filenames if match(f, pattern)]
我真的很喜欢adamk的回答,建议您使用来自同名模块的glob()。这允许您使用*s进行模式匹配。
但正如其他人在评论中指出的,glob()可能会被不一致的斜线方向绊倒。为了帮助实现这一点,我建议您在os.path模块中使用join()和expanduser()函数,也可以在os模块中使用getcwd()函数。
例如:
from glob import glob
# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')
上面的情况很糟糕-路径已被硬编码,并且只能在Windows上在驱动器名称和硬编码到路径之间工作。
from glob import glob
from os.path import join
# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))
上面的方法效果更好,但它依赖于文件夹名Users,该文件夹名在Windows中常见,而在其他操作系统中不常见。它还依赖于具有特定名称admin的用户。
from glob import glob
from os.path import expanduser, join
# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))
这在所有平台上都非常有效。
另一个很好的例子,它可以在不同的平台上完美运行,并且做了一些不同的事情:
from glob import glob
from os import getcwd
from os.path import join
# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))
希望这些示例能帮助您了解在标准Python库模块中可以找到的一些函数的功能。
仅获取文件列表(无子目录)的单行解决方案:
filenames = next(os.walk(path))[2]
或绝对路径名:
paths = [os.path.join(path, fn) for fn in next(os.walk(path))[2]]
初步说明
尽管问题文本中的文件和目录术语有明显的区别,但有些人可能会认为目录实际上是特殊的文件语句:“目录的所有文件”可以用两种方式解释:仅所有直接(或级别1)后代整个目录树中的所有子体(包括子目录中的子体)当问到这个问题时,我认为Python 2是LTS版本,但是代码示例将由Python 3(.5)运行(我将尽可能保持它们与Python 2兼容;此外,我将发布的任何属于Python的代码都来自v3.5.4,除非另有规定)。这会产生与问题中的另一个关键词相关的后果:“将它们添加到列表中”:在Python 2.2之前的版本中,序列(可迭代)主要由列表(元组、集合…)表示在Python2.2中,引入了生成器([Python.Wiki]:生成器)的概念-由[Python.Docs]提供:简单语句-yield语句)。随着时间的推移,返回/处理列表的函数开始出现生成器对应项在Python 3中,生成器是默认行为不确定返回列表是否仍然是必需的(或者生成器也会这样做),但将生成器传递给列表构造函数将从中创建列表(并使用它)。下面的示例说明了[Python.Docs]上的差异:内置函数-map(function,iterable,*iterables)>>>导入系统>>>>>>系统版本'2.7.10(默认值,2016年3月8日,15:02:46)[MSC v.1600 64位(AMD64)]'>>>m=map(lambda x:x,[1,2,3])#只是一个伪lambda函数>>>m,类型(m)([1,2,3],<type'list'>)>>>长度(m)3.>>>导入系统>>>>>>系统版本“3.5.4(v3.5.4:3f56838,2017年8月8日,02:17:05)[MSC v.1900 64位(AMD64)]”>>>m=映射(λx:x,[1,2,3])>>>m,类型(m)(<映射对象位于0x000001B4257342B0>,<class‘map‘>)>>>长度(m)回溯(最近一次调用):文件“<stdin>”,第1行,在<module>中TypeError:“map”类型的对象没有len()>>>lm0=list(m)#从生成器生成列表>>>lm0,类型(lm0)([1,2,3],<class'list'>)>>>>>>lm1=list(m)#从同一生成器生成列表>>>lm1,type(lm1)#现在清空列表-生成器已耗尽([],<class'list'>)这些示例将基于一个名为root_dir的目录,其结构如下(此示例适用于Win,但我也在Nix上使用相同的树)。注意,我将重用控制台:[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q003207219]>sop.bat###设置较短的提示,以便粘贴到StackOverflow(或其他)页面时更适合###[提示]>[提示]>tree/f“root_dir”卷Work的文件夹PATH列表卷序列号为00000029 3655:6FDE: \WORK\DEV\STACKOVERFLOW\Q003207219\ROOT_DIR¦文件0¦文件1¦+---目录0¦+---dir00¦¦¦file000¦ ¦ ¦¦¦+---dir000¦¦文件0000¦ ¦¦+---方向01¦¦文件010¦¦文件011¦ ¦¦+---方向02¦+---方向020¦+---方向0200+---目录1¦文件10¦文件11¦文件12¦+---目录2¦¦文件20¦ ¦¦+---方向20¦文件200¦+---目录3
解决
程序化方法
1.[Python.Docs]:os.listdir(路径=“.”)
返回一个列表,其中包含按路径给定的目录中的条目名称。列表按任意顺序排列,不包括特殊条目“”和“..”。。。
>>>导入操作系统>>>>>>root_dir=“root_dir”#相对于当前目录的路径(os.getcwd())>>>>>>os.listdir(root_dir)#列出root_dir中的所有项['dir0','dir1','dir 2','diri3','file0','file 1']>>>>>>[如果os.path.isfile(os.path.jjoin(root_dir,item)),则os.listdir(root_dr)中的item for item]#过滤项目并仅保留文件(删除目录)[“文件0”,“文件1”]
更详细的示例(code_os_listdir.py):
#!/usr/bin/env python
import os
import sys
from pprint import pformat as pf
def _get_dir_content(path, include_folders, recursive):
entries = os.listdir(path)
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
yield entry_with_path
if recursive:
for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
yield sub_entry
else:
yield entry_with_path
def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
for item in _get_dir_content(path, include_folders, recursive):
yield item if prepend_folder_name else item[path_len:]
def _get_dir_content_old(path, include_folders, recursive):
entries = os.listdir(path)
ret = list()
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
ret.append(entry_with_path)
if recursive:
ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
else:
ret.append(entry_with_path)
return ret
def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
def main(*argv):
root_dir = "root_dir"
ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
lret0 = list(ret0)
print("{:} {:d}\n{:s}".format(ret0, len(lret0), pf(lret0)))
ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
print("\n{:d}\n{:s}".format(len(ret1), pf(ret1)))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
笔记:
有两种实现方式:一种使用生成器的方法(当然,这里似乎没有用,因为我立即将结果转换为列表)经典的(函数名以_old结尾)使用递归(进入子目录)对于每个实现,有两个功能:以下划线(_)开头的一个:“private”(不应直接调用)-完成所有工作公共路径(前一个的包装器):它只是从返回的条目中剥离初始路径(如果需要)。这是一个丑陋的实现,但这是我目前唯一能想到的想法就性能而言,生成器通常会快一点(考虑到创建和迭代时间),但我没有在递归函数中测试它们,而且我还在函数内部迭代内部生成器-不知道这对性能有多友好玩弄争论以获得不同的结果
输出:
[提示]>“e:\Work\Dev\VEnvs\py_pc064_03.05.04_test0\Scripts\python.exe”“.\code_os_listdir.py”Python 3.5.4(v3.5.4:3f56838,2017年8月8日,02:17:05)[MSC v.1900 64位(AMD64)]win32上的064bit<0x000002C080418F68处的生成器对象get_dir_content>22['root_dir\\dir0','root_dir\\dir0\\dir00','root_dir\\dir0\\dir00\\dir000',“root_dir\\dir0\\dir00\\dir000\\file0000”,'root_dir\\dir0\\dir00\\file000',“root_dir\\dir0\\dir01”,“root_dir\\dir0\\dir01\\file010”,“root_dir\\dir0\\dir01\\file011”,'root_dir\\dir0\\dir02',“root_dir\\dir0\\dir02\\dir020”,“root_dir\\dir0\\dir02\\dir020\\dir0200”,'root_dir\\dir1','root_dir\\dir1\\file10','root_dir\\dir1\\file11','root_dir\\dir1\\file12','root_dir\\dir2','root_dir\\dir2\\dir20','root_dir\\dir2\\dir20\\file200','root_dir\\dir2\\file20','root_dir\\dir3',“root_dir\\file0”,'root_dir\\file1']11['dir0\\dir00\\dir000\\file0000','dir0\\dir00\\file000',“dir0\\dir01\\file010”,“dir0\\dir01\\file011”,'dir1\\file10','dir1\\file11','dir1\\file12','dir2\\dir20\\file200','dir2\\file20',“文件0”,'文件1']完成。
2.[Python.Docs]:os.scandir(路径=“.”)
仅在Python 3.5+中,backport:[PyPI]:scandir:
返回一个os.DirEntry对象的迭代器,这些对象对应于路径给定的目录中的条目。条目按任意顺序生成,特殊条目“.”和“..”不包括在内。使用scandir()而不是listdir()可以显著提高同样需要文件类型或文件属性信息的代码的性能,因为os.DirEntry对象在扫描目录时如果操作系统提供了这些信息,就会暴露这些信息。所有os.DirEntry方法都可以执行系统调用,但is_dir()和is_file()通常只需要对符号链接进行系统调用;os.DirEntry.stat()在Unix上总是需要一个系统调用,但在Windows上只需要一个符号链接。
>>>导入操作系统>>>>>>root_dir=os.path.join(“.”,“root_dir”)#明确地在当前目录前面加上前缀>>>根目录(_D)'.\\根目录'>>>>>>scandir_iterator=os.scandir(root_dir)>>>斯堪的纳维亚人<nt.ScandirIterator对象位于0x00000268CF4BC140>>>>[scandir_iterator中项目的item.path]['.\\root_dir\\dir0','.\\root_dir\\dir 1','.\\root_dir\\ dir2','..\\root_dir \\dir3','./\root_dir \\ file0',''.\\root-dir\\file1']>>>>>>[scandir_iterator]中的item.path#将产生一个空列表,因为它被上一次迭代使用(由列表理解自动执行)[]>>>>>>scandir_iterator=os.scandir(root_dir)#重新初始化生成器>>>对于scandir_iterator中的项目:…如果os.path.isfile(item.path):…打印(项目名称)...文件0文件1
笔记:
类似于os.listdir但它也更灵活(并提供更多功能),更具Python风格(在某些情况下,速度更快)
3.[Python.Docs]:os.walk(top,topdown=True,oneror=None,followlinks=False)
通过自上而下或自下而上遍历目录树,在目录树中生成文件名。对于树中以目录顶端为根的每个目录(包括顶端本身),它生成一个三元组(目录路径、目录名、文件名)。
>>>导入操作系统>>>>>>root_dir=os.path.join(os.getcwd(),“root_dir”)#指定完整路径>>>根目录(_D)'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir'>>>>>>walk_generator=os.walk(root_dir)>>>root_dir_intry=next(walk_generator)#第一个条目对应于根目录(作为参数传递)>>>根目录条目('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir',['dir0','dir1','dir 2','diri3'],['file0','file1'])>>>>>>root_dir_entry[1]+root_dir_intry[2]#在单个列表中显示目录和文件(直系后代)['dir0','dir1','dir 2','diri3','file0','file 1']>>>>>>[os.path.join(root_dir_entry[0],item)for root_dir_intry[1]+root_dir-entry[2]中的项]#按完整路径显示前一列表中的所有项['E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0','E:\\Work\\Dev\\StarkOverflow\\ q003207219 \\root_dir \\dir1','A:\\Work\\ Dev\\Stack Overflow\\q003207219\\ root_dir \\ dir2','E:\\Work\\Dev\\ StackOverview\\q003207 219\\root-dir\\dir3','E:\\Work\\Def\\StackOverflow\\q002207219\\root_dir\\file0','E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file1']>>>>>>for walk_generator中的条目:#显示其余元素(对应于每个子分区)…打印(条目)...('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0',['dir00','dir01','dir02'],[])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00',['dir000'],['file000'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00\\dir000',[],['file0000'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir01',[],['file010','file011'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02',['dir020'],[])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020',['dir0200'],[])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200',[],[])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1',[],['file10','file11','file 12'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2',['dir20'],['file20'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2\\dir20',[],['file200'])('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3',[],[])
笔记:
在场景下,它使用os.scandir(旧版本(Python)上的os.listdir)它通过在子文件夹中重复来完成繁重的工作
4.[Python.Docs]:glob.glob(路径名,*,root_dir=无,dir_fd=无,递归=假,include_hinded=假)
或glob.iglob:
返回与路径名匹配的路径名的可能为空的列表,该列表必须是包含路径规范的字符串。路径名可以是绝对的(如/usr/src/Python-1.5/Makefile)或相对的(如../../Tools/*/*.gif),并且可以包含shell样式的通配符。断开的符号链接包含在结果中(如外壳中)。。。。在3.5版中更改:支持使用“**”的递归globs。
>>>导入glob,os>>>>>>通配符模式=“*”>>>root_dir=os.path.join(“root_dir”,通配符模式)#匹配每个文件/目录名>>>根目录(_D)'root_dir\\*'>>>>>>glob_list=glob.glob(root_dir)>>>glob_list(全局列表)['root_dir\\dir0','root_dir \\dir1','root _dir\\dir 2','root_dir \\dir 3','oot_dir \\file0','root_dir \\ file1']>>>>>>[item.replace(“root_dir”+os.path.sep,“”)for glob_list中的项]#从开始处去掉目录名和路径分隔符['dir0','dir1','dir 2','diri3','file0','file 1']>>>>>>对于glob.iglob中的条目(root_dir+“*”,递归=True):…打印(条目)...根目录(_D)\根目录\目录0根目录\dir0\dir00根目录\dir0\dir00\dir000root_dir\dir0\dir00\dir000\file0000root_dir\dir0\dir00\file000根目录\dir0\dir01root_dir\dir0\dir01\file010根目录\dir0\dir01\file011根目录\dir0\dir02根目录\dir0\dir02\dir020根目录\dir0\dir02\dir020\dir0200根目录\目录1根目录\dir1\file10根目录\dir1\file11根目录\dir1\file12根目录\目录2根目录\dir2\dir20root_dir\dir2\dir20\file200根目录\dir2\file20根目录\目录3根目录\文件0根目录\文件1
笔记:
使用os.listdir对于大型树(尤其是在启用递归时),首选iglob允许基于名称的高级筛选(由于通配符)
5.[Python.Docs]:类pathlib.Path(*路径段)
Python 3.4+,backport:[PyPI]:pathlib2。
>>>导入路径库>>>>>>root_dir=“root_dir”>>>root_dir_instance=路径库路径(root_dir)>>>根目录实例Windows路径('root_dir')>>>根目录实例名称'根目录'>>>root_dir_instance.is_dir()真的>>>>>>[root_dir_instance.glob(“*”)中项目的item.name]#通配符搜索所有直接子项['dir0','dir1','dir 2','diri3','file0','file 1']>>>>>>如果不是item.is_dir(),则root_dir_instance.glob(“*”)中的项的os.parent.join(item.parent.name,item.name)]#仅显示文件的路径(包括父项)['root_dir\\file0','root_dir \\file1']
笔记:
这是实现我们目标的一种方式这是OOP风格的处理路径提供大量功能
6.[Python 2.Docs]:dircache.listdir(路径)
仅Python 2但是,根据[GitHub]:python/cpython-(2.7)cpython/Lib/dircache.py,它只是os.listdir上的一个带有缓存的(薄)包装器
def listdir(路径):“”“使用缓存列出目录内容。”“”尝试:cached_mtime,列表=缓存[路径]del缓存[路径]除了KeyError:cached_mtime,列表=-1,[]mtime=os.stat(路径).st_time如果mtime!=cached_mtime(缓存时间):list=os.listdir(路径)list.sort()cache[path]=mtime,列表返回列表
7.本机OS API
POSIX特定:
[Man7]:打开(3)[Man7]:读取指令(3)[Man7]:结束(3)
通过[Python.Docs]提供:ctypes-Python的外部函数库:
ctypes是Python的外部函数库。它提供与C兼容的数据类型,并允许调用DLL或共享库中的函数。它可以用来用纯Python包装这些库。
不直接相关,但请检查[SO]:在使用ctypes之前,通过ctypes从Python调用的C函数返回错误的值(@CristiFati的答案)。
代码_类型.py:
#!/usr/bin/env python3
import ctypes as cts
import sys
DT_DIR = 4
DT_REG = 8
class NixDirent64(cts.Structure):
_fields_ = (
("d_ino", cts.c_ulonglong),
("d_off", cts.c_longlong),
("d_reclen", cts.c_ushort),
("d_type", cts.c_ubyte),
("d_name", cts.c_char * 256),
)
NixDirent64Ptr = cts.POINTER(NixDirent64)
libc = this_process = cts.CDLL(None, use_errno=True)
opendir = libc.opendir
opendir.argtypes = (cts.c_char_p,)
opendir.restype = cts.c_void_p
readdir = libc.readdir
readdir.argtypes = (cts.c_void_p,)
readdir.restype = NixDirent64Ptr
closedir = libc.closedir
closedir.argtypes = (cts.c_void_p,)
def get_dir_content(path):
ret = [path, [], []]
pdir = opendir(cts.create_string_buffer(path.encode()))
if not pdir:
print("opendir returned NULL (errno: {:d})".format(cts.get_errno()))
return ret
cts.set_errno(0)
while True:
pdirent = readdir(pdir)
if not pdirent:
break
dirent = pdirent.contents
name = dirent.d_name.decode()
if dirent.d_type & DT_DIR:
if name not in (".", ".."):
ret[1].append(name)
elif dirent.d_type & DT_REG:
ret[2].append(name)
if cts.get_errno():
print("readdir returned NULL (errno: {:d})".format(cts.get_errno()))
closedir(pdir)
return ret
def main(*argv):
root_dir = "root_dir"
entries = get_dir_content(root_dir)
print("Entries:\n{:}".format(entries))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
笔记:
它从LibC加载三个函数(LibC.so-在当前进程中加载)并调用它们(有关更多详细信息,请检查[so]:如何检查文件是否无异常存在NixDirent64是我的Ubuntu操作系统[Man7]:dirent.h(0P)中structdirent64的CTypes表示(DT_常量也是如此)。在其他风格/版本上,结构定义可能有所不同,如果是这样,则应更新CTypes别名,否则将产生未定义的行为它以os.walk的格式返回数据。我没有费心使其递归,但从现有代码开始,这将是一项相当简单的任务在Win上一切都是可行的,数据(库、函数、结构、常量……)不同
输出:
[cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q003207219]>python3.5./code_ctypes.pyPython 3.5.10(默认,2022年1月15日,19:53:00)[GCC 9.3.0]linux上的064bit条目:['root_dir',['dir0','dir1','dir2','dir3'],['file0','file1']]完成。
8.[TimGolden]:win32file.FindFilesW
特定于获胜:
使用Windows Unicode API检索匹配文件名的列表。API FindFirstFileW/FindNextFileW/Findclose函数的接口。
>>>导入操作系统,win32file作为wfile,win32con作为wcon>>>>>>root_dir=“root_dir”>>>root_dir通配符=os.path.join(root_dir,“*”)>>>entry_list=wfile.FindFilesW(root_dir_w通配符)>>>len(entry_list)#不要显示整个内容,因为它太长8.>>>[entry[-2]for entry_list]#仅显示条目名称[“.”、“..”、“dir0”、“dir1”、“dir2”、“dir 3”、“file0”、”file1“]>>>>>>如果条目[0]&wcon.FILE_ATTRIBUTE_DIRECTORY和条目[-2]不在(“.”,“..”)中,则为entry_list中的条目[条目[-2]]#筛选条目并仅显示目录名称(除了自身和父项)['dir0','dir1','dir 2','dir3']>>>>>>如果条目[0]&(wcon.FILE_ATTRIBUTE_NORMAL|wcon.FILE.ATTRIBUTE ARCHIVE)]#只显示文件的“完整”名称['root_dir\\file0','root_dir \\file1']
笔记:
win32file.FindFilesW是[GitHub]:mhammad/pywin32-Python for Windows(pywin32)扩展的一部分,它是WinAPI上的Python包装
9.使用一些(其他)第三方软件包
最有可能的是,将依赖于上述一项(或多项)(可能有轻微的定制)。
笔记:
代码是指可移植的(针对特定区域的地方除外-标记)或交叉:操作系统(Nix、Win、)Python版本(2、3、)在上述变体中使用了多种路径样式(绝对路径样式、相对路径样式),以说明所使用的“工具”在这个方向上是灵活的os.listdir和os.scandir使用opendir/readdir/closdir([MS.Learn]:FindFirstFileW函数(fileapi.h)/[MS.Learn]:FindNextFileW函数win32file.FindFilesW也使用这些(Win特定)函数(通过[GitHub]:mhammad/pywin32-(main)pywin32/win32/src/win32file.i)_get_dircontent(从第1点开始)可以使用这些方法中的任何一种实现(有些需要更多的工作,有些需要更少的工作)可以执行一些高级过滤(而不仅仅是文件与目录):例如,include_folders参数可以被另一个参数(例如,filter_func)替换,这是一个以路径为参数的函数:filter_func=lambda x:True(这不会删除任何内容),而在_get_dir_content中类似:如果不是filter_fun(entry_with_path):continue(如果函数有一个条目失败,它将被跳过),但代码越复杂,执行时间就越长Nota Bene!由于使用了递归,我必须提到我在我的笔记本电脑(Win 10 pc064)上做了一些测试,与这个问题完全无关,当递归级别达到(990..1000)范围内的某个值时(recursionlimit-1000(默认)),我得到了StackOverflow:)。如果目录树超过了这个限制(我不是FS专家,所以我不知道这是否可能),这可能是一个问题。我还必须提到,我没有尝试增加递归限制,但理论上,如果目录深度大于最高可能的递归限制(在该机器上),则始终存在失败的可能性。检查[SO]:_csv.Error:field大于字段限制(131072)(@CristiFati的答案)以了解有关该主题的更多详细信息代码示例仅用于演示目的。这意味着我没有考虑错误处理(我不认为有任何try/except/else/finally块),所以代码不健壮(原因是:尽量保持简单和简短)。对于生产,还应添加错误处理
其他方法:
1.仅将Python用作包装器
一切都是使用另一种技术完成的该技术是从Python调用的我所知道的最著名的风格是我所称的SysAdmin方法:使用Python(或任何编程语言)执行Shell命令(并解析其输出)有些人认为这是一个很好的方法我认为它更像是一个蹩脚的变通方法(gainarie),因为操作本身是从Shell(在本例中为Cmd)执行的,因此与Python无关过滤(grep/findstr)或输出格式化可以在两方面进行,但我不会坚持这样做。此外,我故意使用os.system而不是[Python.Docs]:subprocess-subprocess管理例程(run,check_output,…)
[提示]>“e:\Work\Dev\VEnvs\py_pc064_03.05.04_test0\Scripts\python.exe”-c“导入os;os.system(\”dir/b root_dir“)”目录0目录1目录2目录3文件0文件1
[cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q003207219]>python3.5-c“import os;os.system(\”ls root_dir\“)”目录0目录1目录2目录3文件0文件1
一般来说,应该避免这种方法,因为如果某些命令输出格式在操作系统版本/风格之间略有不同,那么解析代码也应该进行调整,更不用说地区之间的差异了。
我更喜欢使用glob模块,因为它可以进行模式匹配和扩展。
import glob
print(glob.glob("/home/adam/*"))
它可以直观地进行模式匹配
import glob
# All files and directories ending with .txt and that don't begin with a dot:
print(glob.glob("/home/adam/*.txt"))
# All files and directories ending with .txt with depth of 2 folders, ignoring names beginning with a dot:
print(glob.glob("/home/adam/*/*.txt"))
它将返回一个包含查询文件和目录的列表:
['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
注意,glob忽略以点开头的文件和目录。,因为这些被认为是隐藏的文件和目录,除非模式类似于.*。
使用glob.escape转义不应该是模式的字符串:
print(glob.glob(glob.escape(directory_name) + "/*.txt"))
推荐文章
- 如何从matplotlib (pyplot。Figure vs matplotlib。figure) (frameon=False matplotlib中有问题)
- django test app error -在创建测试数据库时出现错误:创建数据库的权限被拒绝
- 识别使用pip安装的python包的依赖关系
- 从字符串变量导入模块
- 如何删除Python中的前导空白?
- python中的assertEquals和assertEqual
- 如何保持Python打印不添加换行符或空格?
- 为什么Python的无穷散列中有π的数字?
- Python 3.7数据类中的类继承
- 如何在PyTorch中初始化权重?
- 计数唯一的值在一列熊猫数据框架像在Qlik?
- 使用Pandas将列转换为行
- 从matplotlib中的颜色映射中获取单个颜色
- 将Pandas或Numpy Nan替换为None以用于MysqlDB
- 如何从查找“类型d”中排除此/ current / dot文件夹