文章目录
文件,目录操作
Point1
当路径不存在时,抛出异常。一般用于判断传入函数的路径参数是否合法。
assert os.path.exists(data_folder), "Folder " + data_folder + " does not exist"
python的assert用法
'''
格式:
assert 表达式 [, 参数]
当表达式为真时,程序继续往下执行;
当表达式为假时,抛出AssertionError错误,并将 参数 输出
'''
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
foo('0')
# 代码执行结果
# AssertionError: n is zero!
python的异常和错误
Point2,遍历文件夹
list()函数将元组转为列表
元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中,列表是放于方括号中。
listing_to_explore = [os.path.join(data_folder, f) for f in os.listdir(data_folder + '/')]
os.listdir()
python中的os模块用于和系统进行交互
os.listdir()
参考博客
'''
os.lsitdir()
函数功能:返回一个由文件名和目录名组成的列表
注意:接收的参数必须是一个绝对路径
'''
例如:列举路径path=/home/python/Desktop/
下的所有文件和目录名称
import os
path = '/home/python/Desktop/'
for i in os.listdir(path):
print(i)
注意,os.listdir返回的是当前目录下所有的文件和目录,并不对子目录进行递归访问
os.path.join()
'''
os.path.join()
函数功能:连接两个或更多的路径名组件
如果各组件名首字母不包含’/’,则函数会自动加上
如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃
如果最后一个组件为空,则生成的路径以一个’/’分隔符结尾
'''
import os
Path1 = 'home'
Path2 = 'develop'
Path3 = '/code'
Path10 = Path1 + Path2 + Path3
Path20 = os.path.join(Path1,Path2,Path3)
print 'Path10 = ',Path10
print 'Path20 = ',Path20
# 运行结果
>>> Path10 = homedevelop/code
>>> Path20 = /code
os.path.join()
详细例子参考博客
一个复杂的python语句
listing_to_explore = [os.path.join(data_folder, f) for f in os.listdir(data_folder + '/')]
我认为的这条语句的含义:
=
右边最终执行结果是一个list,赋值给=
左边的变量
=
右边是一个中括号,中括号内部,整体执行流是遍历for f in os.listdir(data_folder + '/')
,对每个f
,执行os.path.join(data_folder, f)
,得到关于f
的绝对路径,每次迭代的os.path.join(data_folder, f)
的返回值作为list中的元素,存在list中,即list_to_explore
中。
python3列表
博客
python3列表函数&方法
函数
len(list)
列表元素个数
方法
list.pop([index=-1])
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
任务
需求:遍历一个给定的路径(如上例中的data_folder),对于路径中具有特定后缀名(.ll
)的文件,提取出该.ll文件
所在文件夹,并将该文件夹的绝对路径名加到一个列表中便于后期处理
项目中给定的路径特点:
- 一开始给定的这个路径,包含多个数据集,每个数据集内部又有很多包含
.ll
文件的目录,并且每个数据集内部包含其他非.ll
文件。 - 如果一个文件夹内部有
.ll文件
,那么这个文件夹内部不再含有其他子文件夹,并且这个文件夹内部的内容有两类,一类是.ll文件
,另一类是.DS_STORE
文件。
data_folder目录结构举例如下:
/*/data_folder 的目录结构
/*/data_folder/dataset1_folder/
/*/data_folder/dataset2_folder/
/*/data_folder/file1
/*/data_folder/file2
/*/data_folder/dataset1_folder/ 的目录结构
/*/data_folder/dataset1_folder/dir1/
/*/data_folder/dataset1_folder/dir2/
/*/data_folder/dataset1_folder/dir3/
/*/data_folder/dataset1_folder/.DS_Store
/*/data_folder/dataset1_folder/file2
/*/data_folder/dataset1_folder/dir1/ 的目录结构
/*/data_folder/dataset1_folder/dir1/1.ll
/*/data_folder/dataset1_folder/dir1/2.ll
/*/data_folder/dataset1_folder/dir1/3.ll
/*/data_folder/dataset1_folder/dir1/*.ll
/*/data_folder/dataset1_folder/dir1/.DS_Store
细节:每个数据集内部可能有多级子目录均包含.ll
文件,因此需要逐级遍历所有可能的子目录
代码如下:
assert os.path.exists(data_folder), "Folder " + data_folder + " does not exist"
folders_raw = list()
listing_to_explore = [os.path.join(data_folder, f) for f in os.listdir(data_folder + '/')]
while len(listing_to_explore) > 0:
f = listing_to_explore.pop()
if os.path.isdir(f):
f_contents = os.listdir(f + '/')
for file in f_contents:
# if it contains raw .ll files
if file[-3:] == '.ll':
folders_raw.append(f)
break
elif os.path.isdir(os.path.join(f, file)):
listing_to_explore.append(os.path.join(f, file))
总结
在python编程的逻辑中,我知道一个文件的绝对路径就可以访问这个文件。
对于查找一个文件夹内的指定的某些文件,并做批量处理。从python的角度看,就是,我把那些满足要求的文件的绝对路径名存在一个列表里,这样我就得到了文件夹内所有的满足要求文件的绝对路径了。然后再调用苦力函数分别处理就完事了。
比如说,我想用python去读取某个文件夹内所有.ll
文件的内容。应该怎么写代码呢?
代码分两部分:
第一部分,文件名层面。我先处理这个文件夹,把文件夹内的所有后缀为.ll
的文件找到,并将其绝对路径存起来。涉及到的接口有:os.path.join(), os.listdir(), os.isdir()
等。
第二部分,读取文件内容。使用相关API即可。
我们会发现,第一部分,对于python访问文件夹,除了调用os模块相关接口,本质上还是字符串的处理,我们最终存储的绝对路径,其本质上也是字符串。
第二部分,如果想访问文件的内容,则必须要有准确的路径,然后再调用相应的API去访问文件内容就可以了。
Point3
enumerate()函数
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
详细例子参考博客,例子给的很好,讲得很清楚
任务
我想遍历一个list,并且显示遍历进度
做法:先获取list的长度,然后再for循环中利用enumberate()函数,在获取list元素及其在列表中的索引(索引以0开头),并这样就得到了当前处理list元素的索引和list长度。
代码:
def construct_xfg_single_raw_folder(params, num_folder):
"""this gets called by the processes started in construct_xfg(), and has been lifted from there to enable multiprocessing."""
folder_counter, folder_raw = params
# Print
print('\n------ Processing raw folder', folder_raw, '(', folder_counter + 1, '/', num_folder, ')')
def main()
folders_raw = list()
# 向folders_raw 添加list元素的代码省略
# ...
# ...
num_folder = len(folders_raw)
for folder_counter, folder_raw in enumerate(folders_raw):
construct_xfg_single_raw_folder(params=(folder_counter, folder_raw), num_folder=num_folder)
总结
写任何程序,一定要对自己要处理的数据的格式有透彻清晰的认识。
如果要处理的数据是文件夹,那么必须首先总结出文件夹的模式,再进行写代码。所谓文件夹的模式,就是,文件夹是否包含子文件夹,是否要处理子文件夹;文件夹中包含的文件都有哪些类型,文件夹中包含的哪些文件是我们感兴趣的,而哪些文件是我们不感兴趣的;等等。分析完这些内容之后,再去写代码。
这样一个流程,既不会让我们花过于冗余的时间在文件夹处理这类非核心工作上,又可以让程序的功能更强大。
我们编程的原则就是,按需写代码。我们哪怕再考虑鲁棒性,也要按需写代码,而不是无缘无故地迁就。