[Python 从入门到放弃] 6. 文件与异常(二)
本章所用test.txt文件可以在( [Python 从入门到放弃] 6. 文件与异常(一))找到并自行创建
现在有个需求,对test.txt中的文本内容进行修改:
(1)将期间的‘:’改为‘ said:’
(2)将修改后的内容以覆盖的形式重新写入到该文件
1.步骤分析:
在( [Python 从入门到放弃] 6. 文件与异常(一))我们提到
在进行文件操作时,需要逐行处理,可以使用迭代器
因为test.txt的内容是:
Man:Is this the right room for an argument? Other Man:I've told once. Man:No you haven't! Other Man:Yes I have. Man:When? Other Man:Just now. Man:No you didn't ...... Other Man:Now let's get one thing quite clear:I most definitely told you! Man:Oh no you did't! Other Man:Oh yes I did!
因为几乎每一行都带有 ‘:’ 需要被处理
所以采用迭代器符合条件需要
现在来看初步代码
ver 1:
the_file=open('f://test.txt',encoding='utf-8') for line in the_file: (role,spoken)=line.split(':') print(role,' said:',spoken) 执行结果: Man said: Is this the right room for an argument? Traceback (most recent call last): #抛出异常 Other Man said: I've told once. File "C:/Users/L/PycharmProjects/untitled3/1.py", line 6, in <module> Man said: No you haven't! Other Man said: Yes I have. (role,spoken)=line.split(':') Man said: When? ValueError: not enough values to unpack (expected 2, got 1) Other Man said: Just now. Man said: No you didn't
程序运行时抛出异常,表明出错
我们来分析一下为什么会抛出异常
先来对比一下结果处理后输出的字符串和原本的:
Man said: No you didn't ''' 1.Man said: No you didn't 这段以及之前的语句都成功处理 2.该字符串后面一行是 ’...........‘ 也就是在处理到这一行时出错 '''
在代码中:
(role,spoken)=line.split(':')的意思时,将字符串line进行分割分割的标记时split()里面的’:‘split()会在line中找出所有冒号,将其切割比如:
原本文件中这一行:Man : No you haven't! 当line读取到这一行时 split(':')会在Man : No you haven't!这个字符串里,从':'的地方开始’切割‘,分成两段 一段为:Man 另一端为:No you haven't! 所以 (role,spoken)=line.split(':') 的意思是: 将前一段赋值给role 后一段赋值给spoken 就这样一行行读下去 当读到文件中 '........'这一行时 由于里面没有':'冒号,split()不知道该从那里切割 所以抛出异常报错
如果当这一行没有’:‘时,说明没有人说话,因此不需要加 ’ said:‘也不需要使用split(),因此就不会报错
ver 2:
the_file=open('f://test.txt',encoding='utf-8') for line in the_file: if not line.find(':')==-1: (role,spoken)=line.split(':') print(role,' said:',spoken) else: print(line) 执行结果: Traceback (most recent call last): File "C:/Users/L/PycharmProjects/untitled3/1.py", line 5, in <module> (role,spoken)=line.split(':') ValueError: too many values to unpack (expected 2) Man said: Is this the right room for an argument? Other Man said: I've told once. Man said: No you haven't! Other Man said: Yes I have. Man said: When? Other Man said: Just now. Man said: No you didn't ...... ''' 1. '.........'终于能正常输出了 这说明在遇到没有冒号的语句时 不会执行split() 2. 使用了find()作为判断条件,先将字符串line调用find()查找冒号,如果冒号不存在,则跳过处理语句,如果冒号存在,则正常处理 3.find()用于查找字符串是否包含某字符,不包含则返回-1 4.虽然避免了split()因没有冒号而引发异常,当似乎又出现了新的异常 '''
新的异常:ValueError: too many values to unpack (expected 2)
我们读一下原文件中的数据:
文件剩余数据: ...... Other Man:Now let's get one thing quite clear:I most definitely told you! Man:Oh no you did't! Other Man:Oh yes I did! 除了'.........'已经能够正常执行处理之外, 其它行还没有执行 我们看一下它的下一行: ’ Other Man:Now let's get one thing quite clear:I most definitely told you! ‘ 这一行里面包含了两个冒号 所以split(’:‘)会将其’切割‘成三段 而我们的赋值语句: (role,spoken)=line.split(':') 只能将前两段赋值给两个变量 剩余一段没有变量与之匹配,一脸懵逼,无所适从,只能报错,抛出异常
到了这里,我们可以发现:处理文本信息时,由于文本信息的特殊性,它并不能按照理想的形式排列,
本文的代码中,以冒号为标记,可以将讲述人与其言语切割成两段,并进行处理
然而,并不代表每一行数据都只存在一个冒号
有时为0个,2个,或者3个等
在ver1中我们遇到了没有冒号的形式
在ver2中采用规避的方法,事先调用find()函数,企图将没有冒号的数据行跳过split()语句
现在,遇到了冒号>1的情况,因此抛出异常
处理方法:
让split()只处理头一个冒号,将字符串’分割‘成两段,其余不管有多少个,都忽略:
(role,spoken)=line.split(':',1) # 这个额外的参数控制‘split()’如何分解
ver 3:
the_file=open('f://test.txt',encoding='utf-8') for line in the_file: if not line.find(':')==-1: (role,spoken)=line.split(':',1) print(role,' said:',spoken) else: print(line)
运行结果: # 正常 Man said: Is this the right room for an argument? Other Man said: I've told once. Man said: No you haven't! Other Man said: Yes I have. Man said: When? Other Man said: Just now. Man said: No you didn't ...... Other Man said: Now let's get one thing quite clear:I most definitely told you! Man said: Oh no you did't! Other Man said: Oh yes I did!
本例中,由于数据的特殊性,导致频出异常
虽然每次根据具体情况修改代码,但是难以确保之后不会出现数据的其它特殊情况
而导致异常
因此,需要有一个良好的异常机制来预防和处理随时都有可能发送的异常
本章结合修改文本数据后重新写回文件之要求,重新修改代码,完整代码如下:
the_file=open('f://test.txt','r',encoding='utf-8') text="" for line in the_file: if not line.find(':')==-1: (role,spoken)=line.split(':',1) str=role+' said:'+spoken else: str=line str+='\n' text+=str the_file.close() the_file=open('f://test.txt','w',encoding='utf-8') the_file.write(text) the_file.close()
:
如果数据文件的格式发生改变,这个代码会有问题,相应地也需要改变条件
if语句使用的条件有点不好读,也不好理解
这个代码有点‘脆弱’....如果再出现另一个异常情况,它就会有问题
[Python 从入门到放弃] 6. 文件与异常(二)的更多相关文章
- [Python 从入门到放弃] 5. 文件与异常(一)
1.文件操作: 文件操作包含读/写 从文件中读取数据 向文件写入数据 Python中内置了open()方法用于文件操作 (更多关于open()BIF介绍 阅读此篇) 基本模板: 1.获取文件对象 2. ...
- python入门学习:9.文件和异常
python入门学习:9.文件和异常 关键点:文件.异常 9.1 从文件中读取数据9.2 写入文件9.3 异常9.4 存储数据 9.1 从文件中读取数据 9.1.1 读取整个文件 首先创建一个pi_ ...
- [Python 从入门到放弃] 1. 列表的基本操作
''' 列表 Create By 阅后即焚 On 2018.1.29 ''' 1. 列表的定义 列表看起来好像其它编程语言中的数组,但列表具备更加强大的功能,它是Python完备的集合对象,现在,你可 ...
- Python从入门到放弃系列(Django/Flask/爬虫)
第一篇 Django从入门到放弃 第二篇 Flask 第二篇 爬虫
- python全栈开发从入门到放弃之文件处理
一.文件处理流程 1.打开文件,得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 事例文件内容 [一棵开花的树] 如何让你遇见我 在我最美丽的时刻 为这 我已在佛前求了五百年 求 ...
- Python从入门到放弃
计算机基础 01 计算机基础之编程 02 计算机组成原理 03 计算机操作系统 04 编程语言分类 Python解释器 05 Python和Python解释器 06 执行Python程序的两种方式 0 ...
- [Python 从入门到放弃] 3. BIF(内建函数)
BIF (built-in functions) Python中提供了70多个内建函数,具备大量的现成功能. BIF不需要专门导入,可以直接使用,拿来就用 1.print() # 在屏幕上打印输出 如 ...
- python从入门到放弃之进程
在理解进程之前我们先了解一下什么是进程的概念吧 以下就是我总结的一些基本的进程概念 进程就是正在运行的程序,它是操作系统中,资源分配的最小单位(通俗易懂点也就是电脑给程序分配的一定内存操作空间).资源 ...
- python从入门到放弃之Tensorflow(一)
Tensorflow使用错误集锦: 错误1 : FutureWarning: Conversion of the second argument of issubdtype from ‘float’ ...
随机推荐
- noip2017d2t2
看数据范围想到状压,我们知道最后是选出一颗生成树,但边权的计算有一些有趣: 我们先选一个点做根:然后就发现边的权和深度有关:那我们按深度dp;即按层dp; dp[i][s]表示前i层选的点集为s,转移 ...
- day29(对象转xml(使用java))
通常使用xStream工具. 将集合,数组,对象转成XML. 导入两个包: xpp3_min-1.1.4c.jar xstream-1.4.4.jar 自定义一个类 package com.baidu ...
- springMVC一个Controller处理所有用户请求的并发问题
有状态和无状态的对象基本概念: 有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的.一般是prototype scope. 无状态对象(Stateless ...
- Class AB与Class D功放
D类功放 又称之为数字功放,其特点是,工作效率高,体积小. D类功放的结构 第一部分为调制器,最简单的只需用一只运放构成比较器即可完成.把原始音频信号加上一定直流偏置后放在运放的正输入 ...
- iOS 应用如何完全支持 IPv6-ONLY 网络?
iOS 应用如何完全支持 IPv6-ONLY 网络?¶ 警告 您当前查看的页面是未经授权的转载! 如果当前版本排版错误,请前往查看最新版本:http://www.cnblogs.com/qin-nz/ ...
- 索引视图DEMO1
--use tempdb ----------------------在创建视图和所有底层表时,必须打开ANSI_NULLS以及QUOTED_IDENTIFIER选项 --SET ANSI_NULLS ...
- bootstrap基础学习小记(三)网格简介
网格系统:网格系统的实现原理非常简单,仅仅是通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统.Bootst ...
- ASP .Net C# ---Excel导入导出方法
导入导出的方法以及引用,可以自行创建一个帮助类 using System;using NPOI.SS.UserModel;using NPOI.XSSF.UserModel;using NPOI.HS ...
- C# WPF 中WebBrowser拖动来移动窗口,改变窗口位置
前言 wpf中的WebBrowser相比之前的winform阉割了不少东西,也增加了不少东西,但是msdn对wpf也没有较好的文档 WebBrowser可以说是一个.NET控件,相对于WPF中的控件, ...
- 设计模式:Builder
简介 建造者模式(Builder),将一个复杂对象的表示和它的构建分离,这样同样的构造过程可以创建出不同的对象状态. 类图 下面的Product是要创建的对象的目标类型,产品. Builder 创建一 ...