python如何利用glob模块,获得指定目录下的文件列表
发布于 作者:苏南大叔 来源:程序如此灵动~本文要说的是python
下的glob
模块,它可以获取指定目录下面的文件列表。使用起来也很简单,就一个函数。然后加个类似正则的文件名字符串表述,就可以了。但是,这个glob
模块有个天然的问题,究竟是什么问题呢?请阅读本文的内容。
大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔碰到的各种各样的代码。本文描述python
的glob
模块,场景是获取目标文件夹下的目标文件路径。测试环境:win10
,python@3.6.8
。
个人观点:
glob.glob
不好用,有天然无法解决的缺陷,不建议使用。看看另外一个解决方案吧。
测试用例
- 目录中有个子目录,子目录中的文件和外部一样。
.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/星星/*.txt | true | √ | √ | √ |
由于星星/星
的表述,会导致编辑器排版错乱,这里请自行替换文字“星星”。
glob
vsiglob
下面是代码范例,主要就是设置两个参数,一个是支持通配符的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()
函数是有问题的。两个参数控制同一件事情,写错一个都不生效。也就是说:路径中写了通配符**
的话,就必须设置recursive
为True
,否则不生效。这显然是有问题的嘛!
搜索特殊文件
在编程项目中,经常会碰到一些特殊文件,比如.htaccess
等,这些文件使用glob.glob()
系列是搜索不到的。这个也是glob.glob()
系列函数的问题之一(待后续讨论)。
需要特殊说明的是:glob.glob()
系列函数,只是拿不到以点开头的文件,但是隐藏文件是可以拿到的。
这个问题是有历史原因的,历史上文件名命名是不可以以点开头的,这是非法的。但是后来,又可以这么命名文件了...所以这个glob.glob
函数可能是被定义于这个事件之前。
相关链接
- https://newsn.net/say/centos-tree.html
- https://newsn.net/say/du-filesize.html
- https://newsn.net/say/mac-md5.html
结束语
这个glob
函数,整体来说,不好用。存在着两个大问题:第一,以点开头的文件无法被搜索到。第二,递归参数和路径参数存在着混淆问题。惯例放个python
相关经验文章的链接:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。