文件读取与异常

文件读取与判断

os模块是调用来处理文件的。

先从最原始的读取txt文件开始吧!

新建一个aaa.txt文档,键入如下英文名篇:

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='')

结果如下

如果文件不存在怎么办?

import os

if os.path.exists('aaa.txt'):
# 业务代码
else:
print('error:the file is not existed.')

split切分

现在我们要把这个桥段转化为第三人称的形式

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!"

关键时刻岂可报错。

首先发现问题出在冒号,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='')

取反:not

结果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()

关注代码本身的目的功能:try...except...捕获处理异常

剧本里的对话千差万别,而我只想要人物的对话。不断增加代码复杂度是绝对不明智的。

python遇到代码错误会以traceback方式告诉你大概出了什么错,并中断处理流程(程序崩了!)。

try...except...类似try...catch语法,允许代码中的错误发生,不中断业务流程。

在上述业务代码中我想统一忽略掉所有

  1. 只显示

  2. 木有冒号的文本行

可以 这么写:

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:路径出错

数据储存到文件

业务代码工作流程可以储存到文件中保存下来。下面先看一个需求:

  1. 分别创建一个名为lilei和hanmeimei的空列表
  2. 删除一个line里面的换行符(replace方法和js中几乎一样。去除左右空格用strip方法)
  3. 给出条件和代码,根据role的值将line添加到适当的列表中
  4. 输出各自列表。

简单说就是一个条件查询的实现。

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('bbb.txt',w')

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都运行一套代码。并且在文件创建后关闭

扩展try语句

当我尝试以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.')
  • finally:无论是否运行成功都执行的代码。
  • locals():告诉你文件是否成功被创建并打开。
  • as xxx:为异常对象命名,并且通过str()转化为字符以便打印,也是一个赋值过程

实在太麻烦了。

with语句

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库介绍

pickle是python语言的一个标准模块,安装python后已包含pickle库,不需要单独再安装。

pickle模块实现了基本的数据序列化和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

一、内存中操作:

import pickle
#dumps 转化为二进制文件
li = [11,22,33]
r = pickle.dumps(li)
print(r) #loads 将二进制数据编译出来
result = pickle.loads(r)
print(result)

二、文件中操作:

#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才是上策。

hand first python 选读(2)的更多相关文章

  1. head first python选读(5)

    python web 开发 犯了低级错误,这本书看了一半了才知道书名应为<head first python>,不是hand first.. 现在开始一个web应用. 总算是熟悉的内容了. ...

  2. hand first python 选读(1)

    列表(list) 基本操作 比如说我要整理一个近期热映的电影列表: movies = ["venom", "My Neighbor Totor", " ...

  3. python之进程与线程

    什么是操作系统       可能很多人都会说,我们平时装的windows7 windows10都是操作系统,没错,他们都是操作系统.还有没有其他的? 想想我们使用的手机,Google公司的Androi ...

  4. python之面相对象程序设计

    一 面向对象的程序设计的由来 面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 面向对象的程序设计:路飞学院版 ...

  5. Python 中的实用数据挖掘

    本文是 2014 年 12 月我在布拉格经济大学做的名为‘ Python 数据科学’讲座的笔记.欢迎通过 @RadimRehurek 进行提问和评论. 本次讲座的目的是展示一些关于机器学习的高级概念. ...

  6. Python基础-week06 面向对象编程基础

    一.面向对象编程 1.面向过程 与 面向对象编程 面向过程的程序设计: 核心是 过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式 ...

  7. 送书福利| Python 完全自学手册

    前言 这里不讨论「能不能学,要不要学,应不应该学 Python」的问题,这里只会告诉你怎么学. 首先需要强调的是,如果 Python 都学不会,那么我建议你考虑别的行业,因为 Python 之简单,令 ...

  8. Python 爬虫系列

    爬虫简介 网络爬虫 爬虫指在使用程序模拟浏览器向服务端发出网络请求,以便获取服务端返回的内容. 但这些内容可能涉及到一些机密信息,所以爬虫领域目前来讲是属于灰色领域,切勿违法犯罪. 爬虫本身作为一门技 ...

  9. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

随机推荐

  1. 003-shell 传递参数

    一.概述 可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 二.实例 以下实例我们向 ...

  2. spring中的缓存--Caching

    1.spring从3.1开始支持缓存功能.spring 自带的缓存机制它只在方法上起作用,对于你使用其他持久化层的框架来讲,是没有影响的,相对来讲这种缓存方式还是不错的选择. 2.提供缓存的接口:or ...

  3. python学习笔记(二)文件操作和集合

    集合: 集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据 集合的作用: 1.它可以把一个列表中重复的数据去掉,而不需要你再写判断 2.可以做关系测试, ...

  4. 网页采集利器 phpQuery

    网页采集利器 phpQuery 2012-02-28 11:43:24|  分类: php|举报|字号 订阅     在网页采集的时候,通常都会用到正则表达式.但是有时候对于正则不太好的同学,比如我, ...

  5. Google Code Jam 2014 总结

    第一次参加ACM竞赛,对自己取得的成绩还满意. Round1A: Rank: 2446 Score: 9 (没有进前1000名,只能拼下次了) Round1B: Rank: 944 Score: 42 ...

  6. GIt-远程仓库(特性)

    本人拜读了廖雪峰老师关于Git的讲述后整理所得 上一节讲的Git在一个仓库中对于文件进行基本管理和这种和SVN的功能类似, 如果只是在一个仓库里管理文件历史,Git和SVN真没啥区别,并没有体现出Gi ...

  7. “凯易迅Calix”实习上机——打折问题

    题目要求: 题目记得不太清楚,大概的意思是一个商店的打折方案如下:设一个客户买了n个商品,价格分别是p1,p2,...,pn (1)第一个商品不打折,即cost=p1; (2)第i个商品的折扣d=mi ...

  8. message from server: "Host '192.168.6.68' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts

    系统或者程序连接数据报错 null, message from server: "Host '192.168.6.68' is blocked because of many connect ...

  9. ffmpeg下载安装和简单应用

    先介绍一下ffmpeg:FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec —这是一个用于多个项目中音频和视频的解码器库,以及libavformat ...

  10. python-静态方法staticmethod、类方法classmethod、属性方法property

    Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def  ...