os模块是调用来处理文件的。html
先从最原始的读取txt文件开始吧!python
新建一个aaa.txt文档,键入以下英文名篇:app
Li Lei:"Hello,Han Meimei." Han Meimei:"Hi,Li Lei.How are you?" Li Lei:"I am fine,thank you.And you?"
同目录下建立一个新的file.py文档函数
import os os.getcwd() data=open('aaa.txt') # 打开文件 print(data.readline(),end='') # 读取文件 print(data.readline(), end='') data.seek(0) # 又回到最初的起点 for line in data: print(line,end='')
结果以下测试
若是文件不存在怎么办?code
import os if os.path.exists('aaa.txt'): # 业务代码 else: print('error:the file is not existed.')
如今咱们要把这个桥段转化为第三人称的形式htm
for line in data: (role,spoken)=line.split(':') print(role,end='') print(' said:',end='') print(spoken,end='')
这里是个极其简单对话区分。若是我把对话稍微复杂点对象
。。。 Han Meimei:"There is a question:shall we go to the bed together?" (pause) Li Lei:"Oh,let us go to the bed together!"
关键时刻岂可报错。blog
首先发现问题出在冒号,split方法容许第二个参数.索引
如下实例展现了split()函数的使用方法:
#!/usr/bin/python str = "Line1-abcdef \nLine2-abc \nLine4-abcd"; print str.split( ); print str.split(' ', 1 );以上实例输出结果以下:
['Line1-abcdef', 'Line2-abc', 'Line4-abcd'] ['Line1-abcdef', '\nLine2-abc \nLine4-abcd']
data = open('aaa.txt') # 打开文件 for line in data: (role,spoken)=line.split(':',1) print(role,end='') print(' said:',end='') print(spoken,end='')
结果pause解析不了。每一行作多一个判断。取反用的是not
方法,查找用的是find
方法。
Python find() 方法检测字符串中是否包含子字符串 str ,若是指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,若是包含子字符串返回开始的索引值,不然返回-1。
find()方法语法:
str.find(str, beg=0, end=len(string))
考虑这样写
for line in data: if not line.find(':')==-1: (role,spoken)=line.split(':',1) print(role,end='') print(' said:',end='') print(spoken,end='') data.close()
剧本里的对话千差万别,而我只想要人物的对话。不断增长代码复杂度是绝对不明智的。
python遇到代码错误会以traceback
方式告诉你大概出了什么错,并中断处理流程(程序崩了!)。
而try...except...
相似try...catch语法,容许代码中的错误发生,不中断业务流程。
在上述业务代码中我想统一忽略掉全部
只显示
木有冒号的文本行
能够 这么写:
for line in data: try: (role,spoken)=line.split(':',1) print(role,end='') print(' said:',end='') print(spoken,end='') except: pass
pass是python中的null语句,理解为啥也不作。
经过这个语法,忽略处理掉了全部没必要要的复杂逻辑。
复杂系统中,aaa.txt多是不存在的,你当然能够用if
读取,还有一个更激进(先进)的写法:
import os try: data = open('aaa.txt') # 打开文件 for line in data: try: (role,spoken)=line.split(':',1) print(role,end='') print(' said:',end='') print(spoken,end='') except: pass except: print('error:could not read the file.')
两种逻辑是不同的,上述是没法读取(可能读取出错),if是路径不存在。因而引起了最后一个问题。
过于通常化的代码,老是不能很好地判断就是是哪出了错。try语句没法判断:到底是文件路径不对仍是别的问题
import os try: data = open('aaa.txt') # 打开文件 for line in data: try: (role,spoken)=line.split(':',1) print(role,end='') print(' said:',end='') print(spoken,end='') except ValueError: # 参数出错 pass except IOError: # 输入输出出错 print('error:could not find the file.')
python中异常对象有不少,可自行查阅。
数据不符合指望格式:ValueError
IOError:路径出错
业务代码工做流程能够储存到文件中保存下来。下面先看一个需求:
- 分别建立一个名为lilei和hanmeimei的空列表
- 删除一个line里面的换行符(replace方法和js中几乎同样。去除左右空格用
strip
方法)- 给出条件和代码,根据role的值将line添加到适当的列表中
- 输出各自列表。
简单说就是一个条件查询的实现。
try: data = open('aaa.txt') lilei = [] hanmeimei = [] for line in data: try: (role, spoken) = line.split(':', 1) spoken = spoken.replace('\n', '') if role == 'Li Lei': lilei.append(spoken) else: hanmeimei.append(spoken) except ValueError: pass data.close() except IOError: print('error:the file is not found.') print(lilei) print(hanmeimei)
很简单。
open方法默认为读模式open('bbb.txt','r')
,写模式对由于open('bbb.txt','w')
。
在同目录下建立一个bbb.txt
写入文件能够用如下命令:
out = open('bbb.txt', 'w') print('we are who we are.', file=out) out.close()
文件访问模式 | 释义 |
---|---|
r | 读取,是为默认模式 |
w | 打开一个文件,覆写文件内容,如没有则建立。 |
w+ | 读取和追加写入(不清除) |
a | 追加写入 |
打开的文件必须运行关闭!
好了,介绍完知识以后能够在上一节代码中分别写入文件吧
try: data = open('aaa.txt') lilei = [] hanmeimei = [] for line in data: try: (role, spoken) = line.split(':', 1) spoken = spoken.strip() if role == 'Li Lei': lilei.append(spoken) else: hanmeimei.append(spoken) except ValueError: pass data.close() try: _lilei = open('lilei.txt', 'w') _hanmeimei = open('hanmeimei.txt', 'w') print(lilei,file=_lilei) print(hanmeimei,file=_hanmeimei) _lilei.close() _hanmeimei.close() print('works completed.') except IOError: print('file error.') except IOError: print('error:the file is not found.')
测试成功,但以上代码有个问题:我须要不管IOError都运行一套代码。而且在文件建立后关闭
当我尝试以read
模式打开一个文件,:
try: data = open('lilei.txt') except IOError as err: print('file error.'+str(err)) finally: if 'data' in locals(): _lilei.close() print('works completed.')
实在太麻烦了。
with语句利用了一个上下文管理协议。有了它就不用些finally
了。
目前为止条件查找的方案是这样的
# ... try: _lilei = open('lilei.txt','w') _hanmeimei = open('hanmeimei.txt','w') print(lilei, file=_lilei) print(hanmeimei, file=_hanmeimei) except IOError as err: print('file error.'+str(err)) finally: if '_lilei' in locals(): _lilei.close() if '_hanmeimei' in locals(): _hanmeimei.close() print('works completed.') except IOError: print('error:the file is not found.')
用with重写以后:
try: with open('lilei.txt','w') as _lilei: print(lilei, file=_lilei) with open('hanmeimei.txt','w') as _hanmeimei: print(hanmeimei, file=_hanmeimei) print('works completed.') except IOError as err: print('file error.'+str(err))
写好以后就很是简洁了。
对于列表数据来讲,直接存字符串是很不合适的。如今我要把第二章中的flatten加进来并加以改造。
# base.py def flatten(_list, count=False, level=0): if(isinstance(_list, list)): for _item in _list: flatten(_item,count,level+1) else: if count: for step in range(level): print("\t", end='') print(_list) else: print(_list)
需求:向flatten添加第四个参数,标识数据写入的位置,并容许缺省。
# base.py def flatten(_list, count=False, level=0,_file=False): if(isinstance(_list, list)): for _item in _list: flatten(_item,count,level+1,_file) else: if count: for step in range(level): print("\t", end='',file=_file) print(_list,file=_file) else: print(_list)
调用
import base as utils try: data = open('aaa.txt') lilei = [] hanmeimei = [] for line in data: try: (role, spoken) = line.split(':', 1) spoken = spoken.strip() if role == 'Li Lei': lilei.append(spoken) else: hanmeimei.append(spoken) except ValueError: pass data.close() try: with open('lilei.txt','w') as _lilei: utils.flatten(lilei,True,0,_lilei) with open('hanmeimei.txt','w') as _hanmeimei: utils.flatten(hanmeimei, True, 0, _hanmeimei) print('works completed.') except IOError as err: print('file error.'+str(err)) except IOError: print('error:the file is not found.')
输出成功
把格局拉高点吧,这仍然是一个高度定制化的代码。
pickle库介绍
pickle是python语言的一个标准模块,安装python后已包含pickle库,不须要单独再安装。
pickle模块实现了基本的数据序列化和反序列化。经过pickle模块的序列化操做咱们可以将程序中运行的对象信息保存到文件中去,永久存储;经过pickle模块的反序列化操做,咱们可以从文件中建立上一次程序保存的对象。
1、内存中操做:
import pickle #dumps 转化为二进制文件 li = [11,22,33] r = pickle.dumps(li) print(r) #loads 将二进制数据编译出来 result = pickle.loads(r) print(result)2、文件中操做:
#dump:以二进制形式打开(读取:rb,写入wb)文件 li = [11,22,33] pickle.dump(li,open('db','wb')) #load ret = pickle.load(open('db','rb')) print(ret)
把二进制文件写入文件中:
try: with open('lilei.txt','wb') as _lilei: # utils.flatten(lilei,True,0,_lilei) pickle.dump(lilei,_lilei) with open('hanmeimei.txt','wb') as _hanmeimei: # utils.flatten(hanmeimei, True, 0, _hanmeimei) pickle.dump(hanmeimei,_hanmeimei) print('works completed.') except IOError as err: print('file error.'+str(err)) except pickle.PickleError as pError: print('err:'+str(pError))
数据已经被写入。
举例说:如何打开lileii.txt并正确编译呢?
new_lilei=[] try: with open('lilei.txt','rb') as _new_lilei: new_lilei = pickle.load(_new_lilei) print(utils.flatten(new_lilei)) except IOError as io: print('err:'+str(io)) except pickle.PickleError as pError: print('pickleError'+str(pError))
测试成功。
用pickle的通用io才是上策。