python文件操作

文件,目录操作

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文件所在文件夹,并将该文件夹的绝对路径名加到一个列表中便于后期处理

项目中给定的路径特点

  1. 一开始给定的这个路径,包含多个数据集,每个数据集内部又有很多包含.ll文件的目录,并且每个数据集内部包含其他非.ll文件。
  2. 如果一个文件夹内部有.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)

总结

写任何程序,一定要对自己要处理的数据的格式有透彻清晰的认识。
如果要处理的数据是文件夹,那么必须首先总结出文件夹的模式,再进行写代码。所谓文件夹的模式,就是,文件夹是否包含子文件夹,是否要处理子文件夹;文件夹中包含的文件都有哪些类型,文件夹中包含的哪些文件是我们感兴趣的,而哪些文件是我们不感兴趣的;等等。分析完这些内容之后,再去写代码。
这样一个流程,既不会让我们花过于冗余的时间在文件夹处理这类非核心工作上,又可以让程序的功能更强大。
我们编程的原则就是,按需写代码。我们哪怕再考虑鲁棒性,也要按需写代码,而不是无缘无故地迁就。

Debug和UnDebug执行流分离

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值