我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文要说的是python下的glob模块,它可以获取指定目录下面的文件列表。使用起来也很简单,就一个函数。然后加个类似正则的文件名字符串表述,就可以了。但是,这个glob模块有个天然的问题,究竟是什么问题呢?请阅读本文的内容。

苏南大叔:python如何利用glob模块,获得指定目录下的文件列表 - python-glob
python如何利用glob模块,获得指定目录下的文件列表(图2-1)

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔碰到的各种各样的代码。本文描述pythonglob模块,场景是获取目标文件夹下的目标文件路径。测试环境:win10python@3.6.8

个人观点:glob.glob不好用,有天然无法解决的缺陷,不建议使用。看看另外一个解决方案吧。

测试用例

苏南大叔:python如何利用glob模块,获得指定目录下的文件列表 - 目录结构
python如何利用glob模块,获得指定目录下的文件列表(图2-2)

  • 目录中有个子目录,子目录中的文件和外部一样。
  • .htaccess是个特殊文件,以点开头。
  • hide.txt是隐藏属性文件。

测试代码:

import glob
f1 = glob.glob('dir/')
f2 = glob.glob('dir/*')
f3 = glob.glob('dir/**')
f4 = glob.glob('dir/*.*')
f5 = glob.glob('dir/',recursive=True)
f6 = glob.glob('dir/*',recursive=True)
f7 = glob.glob('dir/**',recursive=True)
f8 = glob.glob('dir/*.*',recursive=True)

输出结果表明:

路径参数递归参数dir/dir/sub/第一层文件第二层文件hide.txt.htaccess
dir/------
dir/*----
dir/**----
dir/*.*-----
dir/True-----
dir/*True---
dir/**True--
dir/*.*True----

再总结的话,就是:

  • .htaccess文件永远找不到。
  • hide.txt虽然是隐藏文件,但是大多数情况下都找得到。*/*.*/**都包含它。
  • *为第一层下所有目录和文件。
  • *.*为当前层次下,仅含文件,不含目录。
  • **为所有目录及文件,但受到了递归限制。
import glob
f9 = glob.glob('dir/*.txt')
f10 = glob.glob('dir/s?.txt')
f11 = glob.glob('dir/s??.txt')
f12 = glob.glob('dir/s[0-9].txt')
f13 = glob.glob('dir/s[a-z][a-z].txt')
f14 = glob.glob('dir/*.txt',recursive=True)
f15 = glob.glob('dir/s?.txt',recursive=True)
f16 = glob.glob('dir/s??.txt',recursive=True)
f17 = glob.glob('dir/s[0-9].txt',recursive=True)
f18 = glob.glob('dir/s[a-z][a-z].txt',recursive=True)
  • 这种仅针对文件名(例如:*.txt)的通配符写法,无视recursive参数。
  • ?或者[]的表述,都是针对一个字母(例如:?/[0-9])的表述。(意思是就占了一个字母位置)
  • s?返回一个s1,但是不返回suu,需要用s??进行匹配。
import glob
f19 = glob.glob('dir/*.txt')
f20 = glob.glob('dir/星星/*.txt')
f21 = glob.glob('dir/星星/*.txt',recursive=True)
路径参数递归参数第一层文件第二层文件第三层文件
dir/*.txt---
dir/星星/*.txt---
dir/星星/*.txttrue
由于星星/星的表述,会导致编辑器排版错乱,这里请自行替换文字“星星”。

globvsiglob

下面是代码范例,主要就是设置两个参数,一个是支持通配符的pathname,另外一个是支持是否深度递归的布尔参数recursive

import glob
files = glob.glob('dir/**',recursive=True)
print(files)

files = [f for f in glob.iglob('dir/**', recursive=True)]
print(files)

函数调用了两个,一个是glob.glob(),另外一个是glob.iglob(),代码glob.iglob(pathname,recursive=False)的结果是个迭代器,所以使用方式比较特殊。

函数返回值类型
glob.glob()list
glob.iglob()generator

路径通配符表述

glob()函数中的第一个参数pathname,支持通配符操作*,**,?,[]这四个通配符。注意是通配符,并不是正则表达式,两者还是有些区别的。

通配符代表
*0个或多个字符
**匹配所有文件、目录、子目录和子目录里的文件
?代表一个字符
[]匹配指定范围内的一个字符,如[0-9]匹配一个数字

是否递归recursive

recursive取值效果
默认false指的是对pathname制定的那一层扫描得到结果后就返回
recursive=True可以用两个星号**遍历制定的路径的所有子目录和子目录里的文件

对于使用**的情况,苏南大叔个人认为这个glob.glob()函数是有问题的。两个参数控制同一件事情,写错一个都不生效。也就是说:路径中写了通配符**的话,就必须设置recursiveTrue,否则不生效。这显然是有问题的嘛!

搜索特殊文件

在编程项目中,经常会碰到一些特殊文件,比如.htaccess等,这些文件使用glob.glob()系列是搜索不到的。这个也是glob.glob()系列函数的问题之一(待后续讨论)。

需要特殊说明的是:glob.glob()系列函数,只是拿不到以点开头的文件,但是隐藏文件是可以拿到的。

这个问题是有历史原因的,历史上文件名命名是不可以以点开头的,这是非法的。但是后来,又可以这么命名文件了...所以这个glob.glob函数可能是被定义于这个事件之前。

相关链接

结束语

这个glob函数,整体来说,不好用。存在着两个大问题:第一,以点开头的文件无法被搜索到。第二,递归参数和路径参数存在着混淆问题。惯例放个python相关经验文章的链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python